Geben Sie den folgenden Code:Generics Oddity - Ich kann einen Long-Wert in eine Map <String, String> einfügen und es kompiliert und nicht ausfällt zur Laufzeit
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<>();
HashMap<String, Object> dataMap = new HashMap<>();
dataMap.put("longvalue", 5L);
class TestMethodHolder {
<T> T getValue(Map<String, Object> dataMap, String value) {
return (T)dataMap.get(value);
}
}
hashMap.put("test", new TestMethodHolder().<String>getValue(dataMap, "longvalue"));
String value = hashMap.get("test"); // ClassCastException occurs HERE
System.out.println(value);
}
Mir ist es nicht verwunderlich, dass diese Code kompiliert, aber eher, dass die ClassCastException in der get-Zeile auftritt, im Gegensatz zur Put-Zeile darüber, obwohl ich eine fundierte Schätzung habe, was passieren könnte. Da generische Typen zur Laufzeit gelöscht werden, tritt die Umwandlung in getValue() zur Laufzeit nie auf und ist tatsächlich eine Umwandlung in Object. Wenn die Methode wie folgt implementiert würde, würde die Laufzeitumwandlung stattfinden und sie würde (wie erwartet) in der Put-Zeile fehlschlagen. Kann das jemand bestätigen?
class TestMethodHolder {
String getValue(Map<String, Object> dataMap, String value) {
return (String)dataMap.get(value);
}
}
Ist dies ein bekannter Fehler oder Merkwürdigkeit der Verwendung von Generika? Ist es dann eine schlechte Übung, beim Aufruf von Methoden die Notation <> zu verwenden?
Edit: Ich verwende das Standard-Oracle JDK 1.7_03. Eine weitere implizierte Frage von oben: Ist die Umwandlung in der ursprünglichen getValue STILL zur Laufzeit, aber die Besetzung ist eigentlich auf Object - oder ist der Compiler schlau genug, um diese Besetzung aus der Laufzeit überhaupt nicht zu entfernen? Dies könnte den Unterschied erklären, in dem die ClassCastException auftritt, die Benutzer bemerken, wenn sie ausgeführt wird.
Es kompiliert und ausgeführt werden, da Typ Löschung es eine 'Karte machen
@LuiggiMendoza Ich denke, OP weiß das - siehe seinen Abschnitt "Gebildete Vermutung". –
Sie haben eine unkontrollierte Umwandlung von Objekt zu T in 'return (T) dataMap.get (value);'. Sie überschreiben den Compiler hier. – devconsole