سؤال

لقد قمت بتنفيذ هذه الوظيفة:

 static <X,Y> Y castOrNull(X obj) {
  try {
   return (Y)obj;
  }
  catch(ClassCastException e) {
   return null;
  }
 }

هذا يعطيني تحذير المترجم:

Type safety: Unchecked cast from X to Y

الذي لا أفهمه بالضبط. ليس try/catch ما الذي أفعله هنا شيكًا؟ هل يمكنني تجاهل التحذير؟

هل ستعمل وظيفتي كما هو متوقع أم لا؟ كيف يمكنني تنفيذها بشكل صحيح؟

حاولت أيضا مع أ obj instanceof Y تحقق ولكن هذا لا يعمل بسبب الطريقة التي يتعامل بها جافا الأداء.

راجع للشغل ، تبدو هذه الوظيفة مفيدة للغاية بالنسبة لي (لجعل بعض التعليمات البرمجية الأخرى أكثر نظافة). أتساءل ما إذا كانت هذه الوظيفة قد تكون موجودة بالفعل في جافا؟


مثال واحد حيث أريد استخدامه:

    void removeEmptyRawStrings() {
        for(Iterator<Entity> e = entities.iterator(); e.hasNext();) {
            RawString s = castOrNull(e.next());
            if(s != null && s.content.isEmpty()) e.remove();
        }
    }

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

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

المحلول

لذا فإن المشكلة هنا هي أن المعلمة العامة Y عند استخدامها للصب الديناميكي ، يتم التعامل مع Object. لن يرمي CCE أبدًا. يمكنك الحصول على CCE في الدعوة الطريقة ، كما كسرت سلامة النوع الثابت.

ايضا X لا معنى له هنا:

من شبه المؤكد أن الحل الصحيح هو عدم محاولة أي شيء مثل هذا. null سيء. الصب سيء.

ومع ذلك ، إذا كنت مصممًا على كتابة هراء ، فيمكنك تمرير Class هدف:

public static <T> T evilMethod(Class<T> clazz, Object obj) {
    try {
        return clazz.cast(obj);
    } catch (ClassCastException exc) {
        return null;
    }
}

نصائح أخرى

لست متأكدًا تمامًا من أنه سيعمل كما هو متوقع. (يعتمد على ما تتوقعه بالطبع :-) ولكن هذا الرمز سيؤدي على سبيل المثال إلى أ java.lang.ClassCastException (ideone):

public class Main {

    public static void main(String[] args) {
        Integer o = Main.<String, Integer>castOrNull("hello");
    }


    public static <X, Y> Y castOrNull(X obj) {
        try {
            return (Y) obj;
        } catch (ClassCastException e) {
            return null;
        }
    }
}

tom Hawtin حصلت الحل "الصحيح".

يمكنك قمع التحذير في هذه الطريقة إذا كنت تعرف على وجه اليقين أنها ليست مشكلة من خلال التعليق عليها @SuppressWarnings("unchecked")

بفضل الطريقة التي لن تعمل بها هذا الرمز جافا جافا حيث تم تصميم هذا الرمز على الإطلاق. تعد الأدوية المفيدة فقط لفحص نوع الوقت لأن الفئات لا تستخدم معلومات النوع العام في وقت التشغيل.

سيتم تجميع الكود الخاص بك إلى هذا:

 static Object castOrNull(Object obj) {
  try {
   return (Object)obj;//FAIL: this wont do anything
  }
  catch(ClassCastException e) {
   return null;
  }
 }

لن يفشل فريق الممثلين إلى الكائن أبدًا ، ولن يتمتع الرمز المترجم بالوصول إلى الأنواع العامة الموجودة في وقت الترجمة. نظرًا لأن فريق الممثلين لا يحدث بالطريقة التي يجب أن تتلقى بها تحذيرًا لعملية لم يتم التحقق منها.

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