Frage zu Wildcards

altsuh

Grünschnabel
hallo
ich hab ein Problem mit Wildcards, bzw es gibt da etwas was ich nciht verstehe.
Also man setzt ja zB ein <T> in eine Klasse damit man Objekte von dieser Klasse erzeugen kann mit verschiedenen Typen zB integer, string usw.
Wofür ist denn jetzt das <?> gut? Also ohne extends usw. Ein einfaches Fragezeichen. Da kann ich doch auch alles beliebige übergeben ... wo ist da der Sinn? Da kann ich doch gleich bei meinem <T> bleiben? Oder nicht? Ich versteh den Unterschied nicht.
Ich hab schon paar Tutorials etc gelesen, aber mir wird das einfach nicht klar .... evtl fehlt mir ein gutes Beispiel ...
 
Hi,

das bloße Fragezeichen nutzt man, wenn man sich noch nicht auf einen Typ festlegen will:
Java:
public void gibDieListeAus(List<?> liste){
   for(Object e: liste){
      System.out.println(e);
   }
}


gibDieListeAus(new Liste<String>());
Nun kann man jede beliebige Liste der Methode übergeben. Und warum geht dann das hier nicht:
Java:
public void gibDieListeAus(List<Object> liste){
   for(Object e: liste){
      System.out.println(e);
   }
}

gibDieListeAus(new Liste<String>()); //Fehler
Eigentlich sollte das ja auch gehen, da ja jedes Objekt vom Object erbt.
Leider verhindert eine Technik in Java, der/die/das "Type Erasure". Das bedeuted, dass die Generics im Bytecode nahezu "normale" Klassen sind (sie werden wie solche übersetzt). Der Compiler überprüft zum Übersetzungszeitpunkt alle Generics auf die Richtigkeit der Typen; bei der Übersetzung gehen diese Informationen dann verloren (sie werden dann nicht mehr gebraucht, der Bytecode ist ja typsicher).
Nun hast du zur Laufzeit eine Liste von Strings, die in eine Liste von Objekten gepackt werden soll. Diese Klassen haben aber aus der Sicht der JVM überhaupt keinen Bezug zueinander, es findet ja keine Typüberprüfung mehr statt.
Aus diesem Grund wurden Wildcards eingeführt, und das Fragezeichen behält sich, wie gesagt, einen beliebigen Typ vor.

Hier kannst du alles noch mal nachlesen: http://www.angelikalanger.com/Articles/EffectiveJava/31.Wildcards/31.Wildcards.html

Ciao
DosCoder
Im obigen Beipiel mit den List<Object>
 
Zuletzt bearbeitet:
danke für deine Antwort, aber was passiert wenn ich bei
PHP:
public void gibDieListeAus(List<Object> liste){
statt Object ein T benutzte?
Ich versteh den Unterschied zwischen einem Platzhalter wie <T> und dem Fragezeichen <?> nicht, beides ist für mich irgendwie das selbe.
 
Moin,

hast Du Dir denn den (übrigens sehr guten) Link von DosCoder durchgelesen :confused:

Dort steht doch genau dass drin, was Du fragst ....

Wo ist eigentlich der Unterschied in den beiden Lösungen? Immerhin sieht Collection<?> ziemlich genauso aus wie Collection<T>. Gibt es überhaupt einen Unterschied? Der Unterschied liegt darin, dass die Methode mit Collection<?> eine normale, nicht-generische Methode ist, wohingegen die Methode mit Collection<T> eine generische Methode ist. Bei der generischen Methode muss der Compiler erst einmal deduzieren, welcher konkrete Typ für den Typparameter T eingesetzt werden muss. Das macht er beim Aufruf der Methode. Zum Beispiel folgert der Compiler beim Aufruf von newPrintCollection(myStrings), dass T durch String ersetzt werden muss. Eine solche Deduktion ist bei der Methode mit Collection<?> nicht nötig, weil die Methode nicht generisch ist.

Gruß
Klaus
 
Zurück