Generic collections und static typing

clemens1

Neues Mitglied
Hallo,
ich bin heute ueber ein merkwuerdiges Verhalten gestossen, welches ich mir nicht erklaeren kann. Folgender Beispielcode zeigt das Problem:
Java:
List l = new LinkedList();
l.add("hallo");
List<Integer> l2 = l;
Dieser code wird ganz normal ausgefuehrt. Da dies allerdings dazu fuehrt, dass in der Integer Liste auch Strings vorkommen, kann es zur Laufzeit zu Problemen kommen. Ich frage mich, warum dies erlaubt ist und was die Philosophie dahinter ist. Warum soll man einen Typ angeben, wenn dies ja doch nicht verhindert, dass sich Objekte von anderen Typen in der Liste befinden. Wie passt das mit der statischen Typisierung von Java zusammen? In C# konnte ich ein solches Verhalten nicht finden, da es nur generische Collections zu geben scheint.

Gruss
 
Kurz und bündig hat das mit Type-Erasure und Raw-Types zu tun. Ist hier nachzulesen: Type-Erasure und Raw-Type.
Das ganze nennt sich dann heap polution was du an dem Beispiel gebracht hast.

Das ganze kannst du in C# nicht finden, da der dynamische Typ jederzeit zur Verfügung steht.
 
Warum soll man einen Typ angeben, wenn dies ja doch nicht verhindert, dass sich Objekte von anderen Typen in der Liste befinden.
Du musst bei beiden Listen den Typ angeben, damit du sofort eine Warnung bekommst.
Java:
List<String> list1 = new ArrayList<>();
List<Integer> list2 = list1;
Wird bei mir in der IDE rot angestrichen mit der Meldung:
Java:
Error:(11, 31) java: incompatible types: java.util.List<java.lang.String> cannot be converted to java.util.List<java.lang.Integer>
 
Das Problem bei mir war, dass eine third-party library meiner Integer Liste eine andere Liste mit Strings zuweist. Darueber habe ich allerdings keine Kontrolle. Ich war verwundert, dass ich dann zur runtime auf einemal Strings in dieser Liste finde.
Hat die Existenz von heap pollution in Java historische Gruende oder ist das ein "Feature", also pure Absicht?
 
Nein das hat historische Gründe. Generics sind erst mit Java 5 hinzugekommen und Type-Erasure wurde als Folge von Backwardcompatibility eingeführt (und somit auch die Nebenwirkungen).

Also es ist nicht beabsichtigt, sondern einfach ein Tradeoff den man in Kauf nehmen musste.

Tipp: Verwende diese Library nicht!
 

Zurück
Oben