generics لماذا يتم ترجمة هذا الرمز العام في java 8؟




1 Answers

أظن أن هذا هو لأن List هي واجهة. إذا تجاهلنا حقيقة أن String final لثانية واحدة ، فيمكنك ، من الناحية النظرية ، أن يكون لديك فصل extends String (يعني أنه بإمكانك تعيينه إلى s ) ولكنه implements List<Integer> (بمعنى أنه يمكن إرجاعها من newList() ). بمجرد تغيير نوع الإرجاع من واجهة ( T extends List ) إلى فئة ملموسة ( T extends ArrayList ) يمكن أن يستنتج المجمع أنه غير قابل للتخصيص من بعضها البعض ، وينتج خطأ.

هذا ، بالطبع ، ينهار لأن String هي ، في الواقع ، final ، ويمكن أن نتوقع من المجمع أن يأخذ ذلك في الحسبان. IMHO ، إنه خطأ ، على الرغم من أنني يجب أن أعترف بأنني لست خبيراً مصمماً وقد يكون هناك سبب وجيه لتجاهل المعدل final في هذه المرحلة.

java generics compiler-errors java-8

لقد عثرت على جزء من التعليمات البرمجية التي تتساءل عن سبب تجميعها بنجاح:

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>();
    }
}



Related