Heim >Java >javaLernprogramm >So verwenden Sie generische Java-Methoden
Die allgemeine Definition lautet wie folgt, das heißt, vor der Methode wird ein
public class FTest { public <t> List<t> f(T t){...}; }</t></t>
Drei generische Parameter-Inferenzmethoden : #🎜🎜 #
1. Fügen Sie den ermittelten generischen Typ direkt vor f() hinzufTest.<integer>f(xxx)</integer>2. Bestimmen Sie ihn durch Eingabe von Parametern
3. Es kann
Rückgabewert OKint number = 0;
fTest.f(number)
F: Was stimmt mit dem Code unten nicht? Ist toString() da?
List<integer> list = fTest.f(xxx);</integer>
A: test ist eine statische Methode, daher kann sie das T
in der Apublic static
toString() Es gibt kein Problem, toString ist die Methode von Object.
Generische Parameter und Typeliminierung
F: Kann Instanz von zum Vergleich des generischen Parameters T verwendet werden?
public class A<t> { public static void test(T t){ System.out.println(t.toString()); } }</t>
A: Nein, der Compiler meldet einen Fehler.
F: Kann der generische Parameter T mit new T() oder new T[] betrieben werden?
A: Nein, der Compiler meldet einen Fehler.F: Kann ich Methoden in generischen Parameterobjekten aufrufen?
class A<t> { void f(Object arg) if(arg instanceof T) { ... } }</t>
A: Es können nur Methoden von Object aufgerufen werden.
F: Kann T für eine erzwungene Konvertierung verwendet werden?
T.f();
A: Es kann ausgeführt werden, aber die Transformation findet nicht tatsächlich statt und während der Kompilierung wird eine Warnung ausgelöst.
Fragen beim Erstellen eines neuen generischen Objekts
T t = (T)object;
Beantworten Sie die folgende Fragen:
F: Stimmt etwas mit dem folgenden Satz nicht?class Parent{} class Child extends Parent{}
F:
List<parent> list = new ArrayList<child>()</child></parent>
Was sind die Merkmale dieser Liste?
A: Diese Liste kann A a = list.get() aufrufen, aber nicht list.add(new Parent())
List extends Parent> list = new ArrayList<child>();</child>Was sind die Merkmale dieser Liste?
Wer wird unten einen Fehler melden? #
Die von Child c = list.get() oder Parent p = list.get() ausgeführte Operation besteht darin, das interne in das externe Parent oder Child> zu zwingen, was unvernünftig ist Der Compiler geht davon aus, dass die übergeordnete Klasse des untergeordneten
möglicherweise nicht in eine übergeordnete oder untergeordnete Klasse konvertiert wird, und verbietet daher dieses Verhalten (z. B. ist die übergeordnete Klasse des übergeordneten Elements ein Objekt, das Objekt jedoch nicht. Dies ist definitiv möglich in Eltern oder Kind umgewandelt werden). Die von *list.add(new Child()) durchgeführte Operation besteht darin, das externe Kind oder Elternteil während der Eingabe in das interne Super-Kind umzuwandeln Elternklasse.
F:
List super Child> list = new ArrayList<parent>();</parent>Was sind die Merkmale dieser Liste?
PS: Beachten Sie, dass dies nicht bedeutet, dass Sie die Methode get oder add nicht aufrufen können. Wenn Sie jedoch get oder add aufrufen, können Sie Objekt A nicht zum Betrieb verwenden. Das heißt, Sie können nicht add(A) oder A a = get(0)Aber Sie können add(object) oder Object o = get(0)Weil? Es kann in Object konvertiert werden, aber nicht in A.
F: Meldet der folgende Code einen Fehler?list.add(new Child()) list.add(new Parent()) Parent a= list.get(); Child b = list.get()A: Es wird kein Fehler gemeldet. Die Ergebnisse werden normal ausgedruckt.
PECS-Prinzip
Achten Sie auf den Unterschied zwischen dem PECS-Prinzip und dem oben genannten!
Das oben erwähnte ?extend oder ?supert wird bei der Deklaration von Objekten verwendet.
Das PECS-Prinzip wird für Methodeneingabeparameter von generischen Objekten verwendet!
List> list = new ArrayList<a>();</a>Dann ist T der generische Parameter. F: Kann der folgende Code normal ausgeführt werden?
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>A: Es kann nicht normal ausgeführt werden, sowohl pushList als auch pollList melden Fehler
Denn nach der Compilerprüfung geht es davon aus, dass List
F: Wenn wir pushList oben unterstützen möchten, wie sollten wir die Definition der pushList-Methode ändern?
A: Ändern Sie es wie folgt:
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>
Das heißt, der Compiler denkt, dass List
A:
// 把自己的内容塞给输入参数,类似于让输入参数做消费。 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元素的父类容器。
Das obige ist der detaillierte Inhalt vonSo verwenden Sie generische Java-Methoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!