Heim >Java >javaLernprogramm >So verwenden Sie generische Java-Methoden

So verwenden Sie generische Java-Methoden

王林
王林nach vorne
2023-05-01 14:16:062642Durchsuche

Generische Methode

Die allgemeine Definition lautet wie folgt, das heißt, vor der Methode wird ein hinzugefügt

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() hinzu

fTest.<integer>f(xxx)</integer>
2. Bestimmen Sie ihn durch Eingabe von Parametern

3. Es kann

Rückgabewert OK

int 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 A-Instanz nicht erkennen und muss in

public static geändert werden. void test(T t)

toString() Es gibt kein Problem, toString ist die Methode von Object.

Generische Parameter und Typeliminierung

F: Was wird der generische Parameter T zur Laufzeit?

A: In Objekt vereinheitlicht und enthält keine Typinformationen.


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.


So verwenden Sie generische Java-MethodenF: 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

Nehmen Sie zunächst an, dass es zwei Klassen gibt, die Basisklasse Parent und die Unterklasse Child

T t = (T)object;

Beantworten Sie die folgende Fragen:

F: Stimmt etwas mit dem folgenden Satz nicht?

class Parent{}
class Child extends Parent{}

A: Es liegt ein Problem vor, die Zusammenstellung ist falsch. Es gibt keine Eltern-Kind-Beziehung zwischen List und ArrayList

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

    Grund: Die von
  • list.get() durchgeführte Operation besteht darin, die interne -Erweiterung von Parent> bei der Rückgabe zu erzwingen, was sinnvoll ist 🎜#list.add(new Parent()) dient dazu, das externe A in das interne umzuwandeln. Dies ist unvernünftig, da wir nicht wissen, dass dieses übergeordnete Objekt konvertiert werden kann.



    F:
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: So verwenden Sie generische Java-Methoden

List super Child> list = new ArrayList<parent>();</parent>
Was sind die Merkmale dieser Liste?
  • A: Weder get noch add können verwendet werden, es können nur Operationen wie „remove“ ohne Rückgabewert und ohne Eingabe A ausgeführt werden.

    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!

Angenommen, es gibt eine Klasse, die wie folgt definiert ist:

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>
So verwenden Sie generische Java-MethodenA: 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 nicht dasselbe!

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 und List dasselbe sind!

# 🎜🎜#F: Wenn Sie pollList unterstützen möchten, wie ändern Sie die Definition?

A:

// 把自己的内容塞给输入参数,类似于让输入参数做消费。
public void pollList(List super T> t) {
    t.addAll(list);
}

因为是把自己的东西塞给输入参数, 而想要能塞进去,必须保证自己这个T,是输入参数的子类,反过来说,输入参数必须是T的父类,所以用super
于是编译器认为,List 和List super Number>是一个东西,允许!

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen