Warum ist es möglich, im folgenden Code ein String
in ein List<Integer>
einzufügen? Ich habe eine Klasse, die Zahlen in eine Liste von Ganzzahlen einfügt:
Dann habe ich eine separate Klasse, die ein String
in ein List
mit dem numerischen Zeichenfolgenwert "42"
:
Warum löst der Compiler keinen Compilerfehler aus oder gibt die Laufzeitumgebung eine Laufzeitausnahme wie *CastException
, wenn ich String
der Liste der Ganzzahlen hinzufüge? Warum erzeugt System.out.print(list)
eine Ausgabe wie die folgende ohne Ausnahmen?
Was ist der Grund dafür, dass all dies passieren kann?
Dies ist wahrscheinlich ein Beispiel zur Veranschaulichung Typ löschen für Generika (ich empfehle diesen Link zu lesen, um dies vollständig zu verstehen und die entscheidende Rolle, die er in Java-Generika spielt).
list
wird als List<Integer>
deklariert
listValue
übergeben wird, wird es in ein umgewandelt Rohtyp
Object
-Befehl einfach print
auf der Liste auf, was nichts dagegen hat, was er enthält, und so druckt er die Elemente einschließlich der Zeichenkette. Wenn Sie eine Ausnahme sehen möchten, fügen Sie eine Zeile hinzu:
%Vor% Dies wird einen toString
als Compiler werfen, fügt während des Löschens Umwandlungen ein, wo dies notwendig ist, um die Typensicherheit zu schützen.
† Umsetzungen von parametrisierten Typen wie ClassCastException
auf den unformatierten Typ, wie List<Integer>
, geben Ihnen eine Compiler-Warnung, um Ihnen zu sagen, dass genau diese Art von Problem bevorsteht geschehen. Sie können diese Warnung mit List
(oder @SuppressWarnings("unchecked")
, wenn dies der Fall ist) unterdrücken steht Ihnen zur Verfügung ). Dies ist eine gute Möglichkeit, "anzuerkennen", dass Sie etwas tun werden, was zu einer ungeprüften Laufzeitausnahme führt, und hilft auch anderen zukünftigen Programmierern zu sagen, dass etwas Unkonventionelles passieren könnte. Zum Beispiel:
Der Compiler wird
werfenAusnahme im Thread "main" java.lang.ClassCastException: java.lang.String kann nicht in java.lang.Integer 234 um umgewandelt werden com.performance.Main.main (Main.java:26)
, da Sie hier den Typ ArrayList<Integer>();
angegeben haben und wenn Sie eine Zeichenfolge list.add(new String("42"));