? jenis kad bebas
list.add(new Son()); Baris ini akan melaporkan ralat: Kaedah put(Son) tidak ditentukan untuk jenis List
Senarai memanjangkan Bapa> bermaksud "senarai dengan mana-mana jenis yang diwarisi daripada Anak" , pengkompil tidak boleh menentukan jenis yang dipegang oleh Senarai, jadi ia tidak boleh menambah objek dengan selamat. Anda boleh menambah null kerana null boleh mewakili sebarang jenis. Jadi kaedah tambah Senarai tidak boleh menambah sebarang elemen bermakna, tetapi ia boleh menerima tugasan Senarai subjenis sedia ada. Anda boleh cuba melakukan ini: List<? extends Father> list = new LinkedList<Son>();
list.add(new Son());
Salin selepas log masuk
Walaupun anda menentukan jenis Son, anda tidak boleh menambah objek Son menggunakan kaedah tambah. Mengapakah kelas Bapa dan subkelas kelas Bapa tidak boleh ditambahkan pada senarai Mari kita analisanya. Senarai memanjangkan Bapa> bermakna had atas ialah Bapa, dan tugasan berikut adalah sah List<? extends Father> list1 = new ArrayList<Father>();
List<? extends Father> list2 = new ArrayList<Son>();
List<? extends Father> list3 = new ArrayList<LeiFeng>();
Salin selepas log masuk
Jika Senarai > list1 boleh menambah Bapa dan semua subkelas Bapa; >list3 boleh menambah LeiFeng dan semua subkelas LeiFeng. Kod berikut gagal dikompilasi: list1.add(new Father());//error
list1.add(new Son());//error
Salin selepas log masuk
- Sebabnya ialah pengkompil hanya mengetahui bahawa bekas itu adalah Bapa atau kelas terbitannya, tetapi ia tidak mengetahui jenis tertentu. Mungkin Bapa? Mungkin Nak? Mungkin LeiFeng, XiaoMing? Selepas pengkompil melihat bahawa Bapa digunakan untuk tugasan kemudian, jenis parameter dalam koleksi tidak terhad kepada "Bapa". Sebaliknya, ia ditandakan dengan pemegang tempat: CAP#1 untuk menunjukkan menangkap Bapa atau subkelas Bapa Saya tidak tahu kelas tertentu, tetapi kodnya ialah CAP#1. Kemudian sama ada anda ingin memasukkan pengkompil Son, LeiFeng atau Father, anda tidak tahu sama ada ia boleh sepadan dengan CAP#1 ini, jadi anda tidak akan membenarkannya. Jadi perbezaan antara aksara kad bebas > dan parameter jenis ialah kepada pengkompil, semua T mewakili jenis yang sama. Contohnya, dalam kaedah generik berikut, ketiga-tiga T semuanya merujuk kepada jenis yang sama, sama ada String atau Integer.
public <T> List<T> fill(T... t);
Salin selepas log masuk
- Tetapi watak kad bebas > tidak mempunyai kekangan seperti itu> Jadi kesilapan di sini ialah tiada apa yang boleh dimasukkan ke dalam Senarai
- Senarai memanjangkan senarai Bapa> tetapi borang ini masih sangat berguna Walaupun kaedah tambah tidak boleh digunakan, Musim boleh menentukan jenis yang berbeza semasa permulaan. Sebagai contoh:
List<? extends Father> list1 = getFatherList();//getFatherList方法会返回一个Father的子类的list
Salin selepas log masuk
Selain itu, memandangkan kami telah memastikan bahawa apa yang disimpan dalam Senarai ialah kelas Bapa atau salah satu subkelasnya, anda boleh menggunakan kaedah get untuk mendapatkan nilai secara terus: List<? extends Father> list1 = new ArrayList<>();
Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Son son = (Son)list1.get(0);
Salin selepas log masuk
Lower Bound< ;? super T> tidak menjejaskan storan masuk, tetapi pengambilan keluar hanya boleh diletakkan dalam objek Object Sempadan bawah diisytiharkan dengan super, menunjukkan bahawa jenis parameter mungkin yang ditentukan jenis, atau jenis ini Jenis ibu bapa, sehingga Objek. //super只能添加Father和Father的子类,不能添加Father的父类,读取出来的东西只能存放在Object类里
List<? super Father> list = new ArrayList<>();
list.add(new Father());
list.add(new Human());//compile error
list.add(new Son());
Father person1 = list.get(0);//compile error
Son son = list.get(0);//compile error
Object object1 = list.get(0);
Salin selepas log masuk
Oleh kerana sempadan bawah menentukan had bawah kebutiran minimum elemen, ia sebenarnya melonggarkan kawalan jenis elemen bekas. Memandangkan elemen itu ialah kelas asas Bapa, ia boleh disimpan dalam butiran yang lebih kecil daripada Bapa. Atas sebab keselamatan jenis, kita boleh menambah objek Bapa atau mana-mana subkelasnya (seperti Son Walau bagaimanapun, kerana pengkompil tidak mengetahui superclass Bapa kandungan Senarai itu, ia tidak dibenarkan untuk menambah mana-mana superclass tertentu). . Kelas (seperti Manusia). Dan apabila kita membacanya, pengkompil hanya boleh mengembalikan objek Objek tanpa mengetahui jenisnya, kerana Objek ialah kelas nenek moyang muktamad bagi mana-mana kelas Java. Tetapi dalam kes ini, semua jenis maklumat elemen hilang. Prinsip PECSAkhir sekali, mari kita lihat apakah prinsip PECS (Producer Extends Consumer Super) yang sudah difahami dengan baik:
Baca dengan kerap Untuk kandungan, adalah sesuai untuk menggunakan sempadan atas Extends.
Bagi yang kerap menyelitkannya, Nether Super sesuai.
Atas ialah kandungan terperinci Apakah extends T dan super T dalam Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!