Ich bin jetzt wirklich verwirrt. Folgendes ist nicht gestattet:
Java:
MyList<Object> l1 =newMyList<String>();
aber folgendes schon:
Java:
MyList l2 =newMyList<String>();
--> letztendlich sind die Elemente von "l2" dann vom Typ "Object". Das kann doch nicht sein. Wieso ist das eine erlaubt, das andere nicht? Ich mein im Grunde sind beide dasselbe? Bzw. wieso ist denn dann das zweite "l2" nicht vom Typ "String"?
Ja aber das was mir nicht einleuchtet ist: Sowohl l1 als auch l2 sind eigentlich vom selben Typ "Object". Die zweite Liste l2 ist ja auch vom Typ "Object" letztendlich. Das was du sagst sollte für den zweiten Fall doch auch gelten, dass ich eine Liste vom Typ String anlege und versuchen könnte über l2 nicht-Strings in die Liste einzufügen?
Bei der zweiten Variante verwendest du den Rawtype, das sollte man bei Java >= 1.5, wie auch schon im anderen Thread erwähnt, nicht mehr tun. Eben weils zu Problemen kommen kann wenn du plötzlich andere Objekte in die Liste steckst.
EDIT:
Da haben sich unsere Antworten grad überschnitten.
Sowohl l1 als auch l2 sind eigentlich vom selben Typ "Object".
l1 ist vom Typ List<Object>, l2 ist vom Typ List, das ist nen kleiner aber feiner Unterschied.
Das was du sagst sollte für den zweiten Fall doch auch gelten, dass ich eine Liste vom Typ String anlege und versuchen könnte über l2 nicht-Strings in die Liste einzufügen?
Nein, wenn du den Rawtype verwendest kann Java nicht wissen was für eine Liste du da tatsächlich hast, daher darfst du alles einfügen. Hast du stattdessen eine List<Object> weiß Java dass nur Instanzen vom Typ Object reindürfen.
Und wieder überschnitten...
Vor Java 1.5 gabs noch gar keine Generics, daher kommt der (Raw)Type List. Da musste man noch selbst dafür sorgen dass das was man in die Liste packt auch darein darf. Seit den Generics hilft einem da der Compiler. Den Rawtype musste man drin lassen, damit alte Programme kompatibel bleiben.
Beim ersteren hätte die List<String> etwas gegen das Einfügen von Objects, deswegen funktioniert es nicht (@edit: schlampereien mit RawType würde ich mir deswegen auch schenken, dann hagelts irgendwann Exceptions). Beim zweiten fehlt schlicht die Typisierung, das gibt 'ne Warnung. Um es ohne Warnung hinzubekommen, sollte es
Java:
MyList<?> l1 =newMyList<String>();
tun, aber einer solchen Liste liessen sich nur null-Objekte hinzufügen.
Du stellst in dem Beispiel ja auch nichts sinnvolles mit der Liste an. Wenn du irgendwann mal versuchst aus der Liste was konkretes rauszuholen fliegt dir ne ClassCastException wenns nicht vom erwarteten Typ ist.
@Xepuk: Oh doch, da fliegt eine... z.B. wenn man nach "add(0, object)" ein "String string = (String) get(0)" versucht. Das ist prähistorisch... wozu gibt es eigentlich diese Generics? XD Im übrigen verwirft der Compiler sämtliche Generics. Decompilier mal eine Java1.5+ Klasse.
Kommt drauf an, was du darunter verstehst. Wenn im Bytecode ein (sicherer) Cast eingefügt wird, ist das für mich schon kein "Verwerfen".
Andererseits können sie auch "richtig" hinterlegt werden. Gib
Code:
javac
mal den Parameter
Code:
-g
mit. Dann werden die
Code:
Code
-Attribute auch jeweils ein
Code:
LocalVariableTypeTable
-Attribut haben. Dort finden sich die Typparameter in der angegebenen Signatur wieder.
Hat dann zwar keine Auswirkung auf die Ausführung des Codes durch die JVM, ist aber für Debugger oder Decompiler nützlich.
[EDIT]Und dass der Decompiler, den du genutzt hast, dieses Attribut nicht berücksichtigt, ist dessen Manko. Würde mich bei solchen Aussagen also nicht auf Decompiler verlassen. JD-GUI kriegts auch nicht gebacken. Wird Zeit, dass ich mich auch mal an einen ransetze. [/EDIT]
[EDIT]Und dass der Compiler, den du genutzt hast, dieses Attribut nicht berücksichtigt, ist dessen Manko. Würde mich bei solchen Aussagen also nicht auf Decompiler verlassen. JD-GUI kriegts auch nichts gebacken. Wird Zeit, dass ich mich auch mal an einen ransetze. [/EDIT]
Dieses Attribut kann man nur berücksichtigen, wenn es im Bytecode steht und das ist nur bei Entwicklungsklassen (z.B. denen des JDK) der Fall. Distributionen (z.B. Klassen der JRE) haben diese Infos jedoch nicht. Fakt bleibt aber, dass die JVM nach wie vor komplett ohne Generics auskommt, da muss auch nichts gecastet werden, weil der Bytecode von javac bereits überprüft wurde. Generics nicht dekompilieren zu können wäre demnach also kein Manko.
Wie, du willst einen eigenen Decompiler entwickeln? Schau dir mal Jasper an. Neben JD-Gui gibt's auch noch IDA-Pro, aber der disassembled glaub' ich auch nur.
Fakt bleibt aber, dass die JVM nach wie vor komplett ohne Generics auskommt, da muss auch nichts gecastet werden, weil der Bytecode von javac bereits überprüft wurde.
Wie, du willst einen eigenen Decompiler entwickeln? Schau dir mal Jasper an. Neben JD-Gui gibt's auch noch IDA-Pro, aber der disassembled glaub' ich auch nur.
Sieht so aus, als würden beide nur disassemblieren. Bin es irgendwie leid, dass es keinen aktuellen und bugfreien Decompiler gibt (oder ich war bei der Suche bisher nicht erfolgreich). Mit einem eigenen Disassembler bin ich auch fast fertig (jaja, da gibts auch schon so Projekte wie BCEL und ASM, will mich aber nicht auf deren Weiterentwicklung verlassen und nebenbei auch einen Lerneffekt mitnehmen).
Der Code hat gar nichts mehr von Generics, so mein ich das. Wär' ja auch was, wenn's anders wär. Pre 1.5er Javacode liesse sich ja sonst kaum mehr ausführen.