generics لماذا يتم ترجمة هذا الرمز العام في java 8؟
أظن أن هذا هو لأن List
هي واجهة. إذا تجاهلنا حقيقة أن String
final
لثانية واحدة ، فيمكنك ، من الناحية النظرية ، أن يكون لديك فصل extends String
(يعني أنه بإمكانك تعيينه إلى s
) ولكنه implements List<Integer>
(بمعنى أنه يمكن إرجاعها من newList()
). بمجرد تغيير نوع الإرجاع من واجهة ( T extends List
) إلى فئة ملموسة ( T extends ArrayList
) يمكن أن يستنتج المجمع أنه غير قابل للتخصيص من بعضها البعض ، وينتج خطأ.
هذا ، بالطبع ، ينهار لأن String
هي ، في الواقع ، final
، ويمكن أن نتوقع من المجمع أن يأخذ ذلك في الحسبان. IMHO ، إنه خطأ ، على الرغم من أنني يجب أن أعترف بأنني لست خبيراً مصمماً وقد يكون هناك سبب وجيه لتجاهل المعدل final
في هذه المرحلة.
لقد عثرت على جزء من التعليمات البرمجية التي تتساءل عن سبب تجميعها بنجاح:
public class Main {
public static void main(String[] args) {
String s = newList(); // why does this line compile?
System.out.println(s);
}
private static <T extends List<Integer>> T newList() {
return (T) new ArrayList<Integer>();
}
}
ما المثير للاهتمام هو أنه إذا قمت بتعديل التوقيع على الأسلوب newList
مع <T extends ArrayList<Integer>>
فإنه لا يعمل بعد الآن.
التحديث بعد التعليقات والردود: إذا قمت بنقل النوع العام من الطريقة إلى الفئة ، فلن يتم ترجمة الشفرة بعد الآن:
public class SomeClass<T extends List<Integer>> {
public void main(String[] args) {
String s = newList(); // this doesn't compile anymore
System.out.println(s);
}
private T newList() {
return (T) new ArrayList<Integer>();
}
}