Verwenden Entwickler die Sammlungen untypisiert, also mit dem Raw-Typ, so lässt sich nicht verhindern, dass ein ungewünschter Typ die Sammlung betritt und beim Entnehmen zu einer Ausnahme führen kann. Der Grund liegt in der internen Umsetzung, dass nur der Compiler selbst die Typsicherheit sicherstellt, aber nicht die Laufzeitumgebung. Um die Typsicherheit zu erhöhen, bietet die Collections-Klasse ein paar Wrapper-Methoden, die eine Sammlung nehmen und Operationen nur eines gewissen Typs durchlassen – verstoßt ein Aufrufer dagegen, gibt es eine ClassCastException.
class java.util.Collections
§ static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type)
§ static <E> List<E> checkedList(List<E> list, Class<E> type)
§ static <K,V> Map<K,V> checkedMap(Map<K,V> m, Class<K> keyType, Class<V> valueType)
§ static <E> Queue<E> checkedQueue(Queue<E> queue, Class<E> type)
§ static <E> Set<E> checkedSet(Set<E> s, Class<E> type)
§ static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V> m, Class<K> keyType, Class<V> valueType)
§ static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, Class<E> type)
Beispiel: Lasse in eine Menge nur Strings, aber nichts anderes.
Set<String> set = Collections.checkedSet( new HashSet<String>(),
String.class );
set.add( "xyz" ); // Compiler OK
Set rawset = set;
rawset.add( "abc" ); // Compiler OK
rawset.add( new Object() ); // Compiler OK, N Laufzeitfehler
Die Ausnahme ist: “Exception in thread "main" java.lang.ClassCastException: Attempt to insert class java.lang.Object element into collection with element type class java.lang.String”
Auch wenn kein Programmierer freiwillig falsche Typen in eine Sammlung platziert, ist es doch besser, eine absolute Sicherheit zu bekommen, die nicht auf dem Compiler beruht. Wenn etwa ein Programm einer Skriptsprache die Möglichkeit eröffnet Elemente in eine Datenstruktur zu setzen, so lässt sich für die Skriptsprache eine geprüfte Sammlung zur Ablage nach außen geben. Achtet das Skript nicht auf den richtigen Typ, so knallt es im Skript. Das ist gewünscht, denn andernfalls würde viel später erst der falsche Typ bei der Bearbeitung auffallen und dann knallt es an der ganz falschen Stelle.
Was bringt das? Warum sind Generics sonst nicht typsicher?
Und ist ein Generic mit nicht sowieso unproblematisch, weil String final ist?
Korrekt, sicherer werden generische Collections dadurch nicht. Manchmal hat man aber eben das Vergnügen mit raw-types (idR. legacy code) und möchte den eigenen Code vor unerwarteten Objekten aus der Collection schützen. Dabei koennen diese Wrapper-Objekte helfen.