متى يجب استخدام الأسلوب يلقي جافا 5 من الدرجة؟

StackOverflow https://stackoverflow.com/questions/243811

  •  04-07-2019
  •  | 
  •  

سؤال

ويبحث من خلال بعض التعليمات البرمجية جئت عبر التعليمات البرمجية التالية

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

ووأود أن أعرف إذا كان الصب بهذه الطريقة لديه أي مزايا أكثر

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);

ولقد سألت المطور المسؤول وقال انه استخدم لأنه كان جديدا (الذي لا يبدو وكأنه سبب وجيه خاصة بالنسبة لي)، ولكن أنا مفتون عندما كنت ترغب في استخدام هذه الطريقة.

هل كانت مفيدة؟

المحلول

وهذه التصريحات ليست متطابقة. طريقة الصب هو استدعاء الأسلوب العادي (invokevirtual JVM تعليمات) في حين أن الآخر هو بناء لغة (تعليم checkcast). في حال كنت تظهر أعلاه، يجب عليك استخدام النموذج الثاني: (TrTuDocPackTypeDto) packDto

ويستخدم أسلوب cast في البرمجة عاكسة مع الأدوية، عندما يكون لديك مثيل Class للبعض نوع متغير. هل يمكن استخدامها مثل هذا:

public <T> Set<T> find(Class<T> clz, Filter criteria) {
  List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */
  Set<T> safe = new HashSet<T>();
  for (Object o : raw) 
    safe.add(clz.cast(o));
  return safe;
}

وهذا يمنحك وسيلة آمنة لتجنب البديل غير صحيح ببساطة يلقي نوع الخام إلى نوع عام:

/* DO NOT DO THIS! */
List raw = new ArrayList();
...
return (List<Widget>) raw;

والمترجم سوف يحذرك، Unchecked cast from List to List<Widget>، وهذا يعني أنه في القطع، شخص ما يمكن أن يضاف Gadget إلى قائمة الخام، والذي يؤدي في نهاية المطاف ClassCastException عندما بالتكرار المتصل على قائمة عاد من (المفترض) حالات Widget.

نصائح أخرى

والقضية الرئيسية لفعل ذلك (IME) عندما تحتاج للادلاء بأمان في فئة / طريقة عامة. نظرا لنوع المحو، لا يمكن أن يلقي لT لكن إذا كنت قد قدمت معلمة Class<? extends T> ثم يمكنك استخدام ذلك لالمدلى بها وستكون النتيجة احالة إلى متغير من نوع T.

وأنا لا يمكن العثور على سبيل المثال حيث طريقة الصب هو ممكن وبناء الجملة يلقي لا. ومع ذلك، عند النظر إلى رمز، ويبدو أنه في حالة المدلى بها غير ممكن، وطريقة يلقي يلقي ClassCastException مع أي نوع من المعلومات المرفقة، في حين أن بناء الجملة يلقي سوف اعطيكم بعض النصائح (كما هو الحال في "لا يمكن أن يلقي سنوبي لTyrannosorusRex ")  :

/**
 * Casts an object to the class or interface represented
 * by this <tt>Class</tt> object.
 *
 * @param obj the object to be cast
 * @return the object after casting, or null if obj is null
 *
 * @throws ClassCastException if the object is not
 * null and is not assignable to the type T.
 *
 * @since 1.5
 */
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}

ومع النموذج الأول

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

ويمكنك القيام بذلك:

public void dynamicCast( Class clazz, Object o ) { 
     this.x = clazz.cast( o );
}

ومع ثاني لا يمكنك. الطبقة الصب يجب الثابت ترميز.

وماذا كنت تستخدم متغير ليلقي في المقام الأول؟ هذا سؤال آخر. :) أول ما يتبادر إلى الذهن هو، كنت لا تعرف (في وقت الترجمة) الفئة التي سيتم مسبوكة ل.

وكلا من هذه البيانات متطابقة. اختيار أي واحد تجد أكثر قابلية للقراءة. الأسلوب الثاني هو أكثر شيوعا في تجربتي، وهذا هو مرة واحدة أن أنا أفضل.

وأنا أميل إلى استخدام الأسلوب يلقي فقط عندما كنت أعمل مع التفكير، ويقرأ أجمل في هذا الوضع. جميع الأوقات الأخرى أجد نفسي باستخدام الطريقة الثانية من الصب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top