secara amnya ditakrifkan seperti berikut, iaitu,
public class FTest { public <t> List<t> f(T t){...}; }</t></t>
ditambah di hadapan kaedah Tiga kaedah inferens parameter generik:
1. Tambahkan secara langsung jenis generik
fTest.<integer>f(xxx)</integer>
di hadapan f() 2. Tentukan melalui parameter input Inferens berikut ialah Integer
int number = 0; fTest.f(number)
3 lulus OK
rreeeS: Apa yang salah dengan kod di bawah? Adakah toString() ada?
List<integer> list = fTest.f(xxx);</integer>
J: ujian ialah kaedah statik, jadi T
dalam contoh A
ujian kosong
toString() tiada masalah, toString ialah kaedah Object.
S: Apakah parameter generik T akan menjadi pada masa jalan?
J: Disatukan menjadi Objek dan tidak mengandungi sebarang jenis maklumat.
S: Bolehkah instanceof digunakan untuk perbandingan parameter generik T?
public class A<t> { public static void test(T t){ System.out.println(t.toString()); } }</t>
J: Tidak, pengkompil akan melaporkan ralat.
S: Bolehkah parameter generik T dikendalikan dengan T() baharu atau T[] baharu?
J: Tidak, pengkompil akan melaporkan ralat.
S: Bolehkah saya memanggil kaedah dalam objek parameter generik?
class A<t> { void f(Object arg) if(arg instanceof T) { ... } }</t>
J: Hanya kaedah Objek boleh dipanggil.
S: Bolehkah T digunakan untuk penukaran paksa?
T.f();
J: Ia boleh dijalankan, tetapi transformasi sebenarnya tidak akan berlaku, dan amaran amaran akan dicetuskan semasa penyusunan.
Anggapkan terdapat dua kelas, kelas asas Induk dan subkelas Anak
T t = (T)object;
Jawab soalan berikut:
S: Di bawah Adakah terdapat sesuatu yang salah dengan ayat ini?
class Parent{} class Child extends Parent{}
J: Ada masalah, kompilasi salah. Tiada hubungan ibu bapa-anak antara Senarai
S:
List<parent> list = new ArrayList<child>()</child></parent>
Apakah ciri-ciri senarai ini?
J: Senarai ini boleh memanggil A a = list.get(), tetapi tidak boleh list.add(new Induk())
Sebab:
senarai Operasi yang dilakukan oleh .get() adalah untuk memaksa dalaman memanjangkan Parent> ini adalah wajar. untuk menukar A luaran ke dalam extend Parent>
List extends Parent> list = new ArrayList<child>();</child>Apakah ciri-ciri senarai ini?
Siapa yang akan melaporkan ralat di bawah
List super Child> list = new ArrayList<parent>();</parent>J: Tangkapan skrin adalah seperti berikut:
mungkin tidak semestinya ditukar kepada ibu bapa atau anak, jadi tingkah laku ini dilarang (contohnya, kelas induk ibu bapa ialah objek, tetapi objek tidak boleh ditukar kepada ibu bapa atau anak). Operasi yang dilakukan oleh *list.add(new Child()) adalah untuk menukar anak luar atau ibu bapa ke dalam super Child> kelas ibu bapa.
list.add(new Child()) list.add(new Parent()) Parent a= list.get(); Child b = list.get()
Apakah ciri-ciri senarai ini?
J: Dapatkan atau tambah tidak boleh digunakan, hanya operasi seperti alih keluar tanpa nilai pulangan dan tiada input A boleh dilakukan.
PS: Perhatikan, ini tidak bermakna anda tidak boleh memanggil kaedah dapatkan atau tambah, tetapi apabila memanggil dapatkan atau tambah, anda tidak boleh menggunakan objek A untuk beroperasi.Iaitu, anda tidak boleh melakukan add(A) atau A a = get(0)
, tetapi anda boleh melakukan add(objek) atau Object o = get(0)
Sebab? Ia boleh ditukar kepada Objek, tetapi tidak boleh ditukar kepada A.
S: Adakah kod berikut akan melaporkan ralat?
List> list = new ArrayList<a>();</a>
J: Tiada ralat akan dilaporkan. Keputusan akan dicetak seperti biasa.
Prinsip PECS
Perhatikan perbezaan antara prinsip PECS dan di atas!Supert extend atau ? yang disebutkan di atas digunakan semasa mengisytiharkan objek.
Prinsip PECS digunakan untuk parameter input kaedah objek generik!
Andaikan terdapat kelas yang ditakrifkan seperti berikut:
List<fruit> fruitList = new ArrayList(); fruitList.add(new Fruit()); List<apple> appleList = new ArrayList(); appleList.add(new Apple()); fruitList.addAll(appleList); System.out.println(fruitList);</apple></fruit>
Maka T ialah parameter generik.
S: Adakah kod berikut akan berjalan seperti biasa?
public static class MyList<t> { List<t> list = new ArrayList(); // 把输入参数塞给自己,类似于生产操作 public void pushList(List<t> t) { list.addAll(t); } // 把自己的内容塞给输入参数,类似于让输入参数做消费。 public void pollList(List<t> t) { t.addAll(list); } }</t></t></t></t>
J: Ia tidak boleh berjalan secara normal kedua-dua pushList dan pollList akan melaporkan ralat
Kerana selepas menyemak, pengkompil berpendapat bahawa Senarai
S: Jika kita mahu menyokong pushList di atas, bagaimanakah kita harus mengubah suai takrif kaedah pushList?
J: Tukar kepada ini:MyList<number> myList = new MyList(); List<integer> intList = new ArrayList(); myList.pushList(intList); List<object> objectList = new ArrayList(); myList.pollList(objectList);</object></integer></number>
S: Jika anda mahu menyokong pollList , bagaimana untuk mengubah suai definisi?
J:// 把自己的内容塞给输入参数,类似于让输入参数做消费。 public void pollList(List super T> t) { t.addAll(list); }
因为是把自己的东西塞给输入参数, 而想要能塞进去,必须保证自己这个T,是输入参数的子类,反过来说,输入参数必须是T的父类,所以用super
于是编译器认为,List
PECS原则出自Effective Java, 注意只是一个编程建议而已!
如果有一个类A,泛型参数为T
如果他一般只用于接收输入容器List后,塞入自己内部的T容器, 则类A就叫生产者, 因此输入参数最好定义为 extend T>最好, 以便能接收任何T子类的容器。
如果他一般只用于接收输入容器后List, 把自己内部的T元素塞给它, 那么这个类A就叫消费者, 输入参数最好定义为 super T>\ 最好, 以便自己的T元素能塞给任何T元素的父类容器。
Atas ialah kandungan terperinci Cara menggunakan kaedah generik Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!