Heim  >  Artikel  >  Java  >  Was sind die Unterschiede zwischen den Platzhaltern T und ?

Was sind die Unterschiede zwischen den Platzhaltern T und ?

王林
王林nach vorne
2023-05-11 18:10:061324Durchsuche

Die ersten beiden Codeteile:

public static <T> void show1(List<T> list){
 for (Object object : list) {
        System.out.println(object.toString());
    }
}

public static void show2(List<?> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

Sie können sehen, dass wir T in der show1-Methode verwenden. Jeder weiß, dass dies eine gängige Schreibweise für Generika ist, daher bezieht sich T hier auf eine bestimmte Klassenspezifische Objekte können nur Daten desselben Typs in der Listensammlung speichern. Wenn unterschiedliche Datentypen eingefügt werden, wird ein Fehler gemeldet.

Was verwenden wir also in der Show2-Methode? , können Sie sehen, dass vor void kein <t></t> steht? Es kann als Platzhalter ausgedrückt werden und weiß nicht, wie viele Datentypen in der Listensammlung gespeichert werden. Dies zeigt also, dass es auch möglich ist, N Datentypen in unserer Liste zu speichern. <t></t>,?可以表示成占位符,它自己也不知道list集合中会存放多少种类型的数据,所以这样就表明我们的list中存放N种数据类型也是可以的。

我们通过一段测试代码来直观的感受一下二者的区别吧:

public static void test(){
   List<Student> list1 = new ArrayList<>();
   list1.add(new Student("zhangsan",18,0));
   list1.add(new Student("lisi",28,0));
   list1.add(new Student("wangwu",24,1));
   //这里如果add(new Teacher(...));就会报错,因为我们已经给List指定了数据类型为Student
   show1(list1);

   System.out.println("************分割线**************");

   //这里我们并没有给List指定具体的数据类型,可以存放多种类型数据
   List list2 = new ArrayList<>();
   list2.add(new Student("zhaoliu",22,1));
   list2.add(new Teacher("sunba",30,0));
   show2(list2);
}

来看看运行结果:

Student{name='zhangsan', age=18, sex=0}
Student{name='lisi', age=28, sex=0}
Student{name='wangwu', age=24, sex=1}
************分割线**************
Student{name='zhaoliu', age=22, sex=1}
Teacher{name='sunba', age=30, sex=0}

从show2方法可以看出和show1的区别了,list2存放了Student和Teacher两种类型,同样可以输出数据,所以这就是T和?的区别啦~小伙伴们了解了吧

下面来看看?的扩展写法:

List extends 数据类型> list

public static void show3(List<? extends Teacher> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

List extends Teacher> list这种写法表示可以接收Teacher和它的子类数据类型的list集合,写个测试方法show3(list2);试试:

Student{name=&#39;zhaoliu&#39;, age=22, sex=1}
Teacher{name=&#39;sunba&#39;, age=30, sex=0}

可以看到正常输出,因为集合中的数据都是Teacher的子类类型,如果我们将List extends Teacher> list改成List extends Student> list会出现什么情况?

Was sind die Unterschiede zwischen den Platzhaltern T und ?

仔细看这张图,我们新建了一个list3并且声明数据类型为Teacher,这个时候调用show3(List extends Student> list) 就马上会报错的,错误信息提示Teacher不能转换成Student,因为Student是Teacher的子类,而我们只接受Student及它的子类,所以当然会报错了。

List super 数据类型> list

这种写法表示只接收指定的数据类型及它的父类类型,也简单的写段代码看看效果:

public static void show4(List<? super Student> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

可以看出来,我们接收的是Student及它父类的集合,我们写两个集合数据然后调用试试。

List list4 = new ArrayList<>();
list4.add(new Student("sunba",30,0));
list4.add(new Teacher("zhaoliu",22,1));
show4(list4);

在list中插入了一个Student和Teacher对象,看看结果:

Student{name=&#39;sunba&#39;, age=30, sex=0}
Teacher{name=&#39;zhaoliu&#39;, age=22, sex=1}

没毛病,正常运行并输出。

下面我们来看看,如果我们是传递的 Student的子类的集合会咋样

Was sind die Unterschiede zwischen den Platzhaltern T und ?

可以看到和之前的一样,会报错,理由也是一样的,以为我们已经定义了只能接收Student及其父类的数据类型。

最后来看一种情况

如果我定义List的时候没有指定数据类型,并且插入了一个Child,Student,Teacher,还是调用show4(List super Student> list)

Lassen Sie uns den Unterschied zwischen den beiden anhand eines Testcodes intuitiv spüren:

rrreeeWas sind die Unterschiede zwischen den Platzhaltern T und ? Werfen wir einen Blick auf die laufenden Ergebnisse:

#🎜 🎜# Student{name='zhangsan', age=18, sex=0}
Student{name='lisi', age=28, sex=0}
Student{name='wangwu', Alter= 24, Geschlecht=1/>***************Trennlinie**************
Student{name='zhaoliu ', age=22, sex=1}
Teacher{name='sunba', age=30, sex=0}

Sie können den Unterschied zu Show1 aus sehen Mit der Methode show2 speichert list2 zwei Typen: Schüler und Lehrer und kann auch Daten ausgeben. Das ist also der Unterschied zwischen T und ?~ Freunde, verstehst du? Erweiterte Schreibmethode:

Was sind die Unterschiede zwischen den Platzhaltern T und ?List erweitert Datentyp> Liste

rrree

Liste Diese Schreibweise bedeutet, dass Sie eine Listensammlung von Teacher und seinen Unterklassen-Datentypen erhalten können. Schreiben Sie eine Testmethode <code>show3(list2); und versuchen Sie:

rrreee#🎜🎜#Sie können siehe Normale Ausgabe, da es sich bei den Daten in der Sammlung um Unterklassen von Teacher handelt Was geschieht? #🎜🎜##🎜🎜#Platzhalter T und ? in Java-Generika? Was sind die Unterschiede?#🎜🎜##🎜🎜#Sehen Sie sich dieses Bild genau an. Wir haben eine neue Liste3 erstellt und den Datentyp als Lehrer deklariert. Zu diesem Zeitpunkt rufen wir show3(List erweitert Student> list) code> meldet sofort einen Fehler. Die Fehlermeldung zeigt an, dass Teacher nicht in Student konvertiert werden kann, da Student eine Unterklasse von Teacher ist und wir nur Student und seine Unterklassen akzeptieren, sodass natürlich ein Fehler vorliegt gemeldet. #🎜🎜##🎜🎜#<code>List super data type> list#🎜🎜##🎜🎜#Diese Schreibweise bedeutet, dass nur der angegebene Datentyp und sein übergeordneter Typ empfangen werden Schreiben Sie einfach einen Code, um den Effekt zu sehen: #🎜🎜#rrreee#🎜🎜# Es ist ersichtlich, dass wir eine Sammlung von Studenten und ihrer übergeordneten Klasse erhalten. Schreiben wir zwei Datensammlungen und rufen sie dann zum Ausprobieren auf . #🎜🎜#rrreee#🎜🎜#Fügen Sie ein Schüler- und Lehrerobjekt in die Liste ein und sehen Sie sich das Ergebnis an: #🎜🎜#rrreee#🎜🎜#Nichts falsch, es läuft normal und gibt aus. #🎜🎜##🎜🎜#Mal sehen, was passiert, wenn wir eine Sammlung von Student-Unterklassen übergeben#🎜🎜##🎜🎜#Was sind die Unterschiede zwischen den Platzhaltern T und ? in Java-Generika#🎜🎜##🎜🎜#Sie sehen dasselbe wie zuvor. Aus demselben Grund wird ein Fehler gemeldet Wir gehen davon aus, dass wir einen Datentyp definiert haben, der nur Student und seine übergeordnete Klasse empfangen kann. #🎜🎜##🎜🎜#Schauen wir uns zum Schluss eine Situation an #🎜🎜##🎜🎜#Wenn ich beim Definieren einer Liste keinen Datentyp spezifiziere und ein Kind, einen Schüler oder einen Lehrer einfüge, rufe ich trotzdem show4 auf ( List super Student> list), wird ein Fehler gemeldet? Was ist das Ergebnis, wenn kein Fehler gemeldet wird? #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Sie können sehen, dass kein Fehler gemeldet wird, da die Liste mehrere Datentypen speichern kann. Was wird also das Ergebnis sein, wenn die Methode show4 aufgerufen wird? #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Sie können sehen, dass das Programm normal ausgeführt wird und die Ergebnisse ausgibt, weil wir die Objektdatentypen Student und seine übergeordneten Klassen erhalten unser Kind Es erbt von Student, daher konvertiert das Programm unser Kind zur Ausgabe automatisch in die übergeordnete Klasse Student. Daher sollte jeder darauf achten und es wird automatisch nach oben konvertiert. #🎜🎜#

Das obige ist der detaillierte Inhalt vonWas sind die Unterschiede zwischen den Platzhaltern T und ?. 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