11.13 Typsichere Datenstrukturen
 
Die älteren Datenstrukturen Vector, Stack und Hashtable sowie die neuen aus der Collection-API haben einen großen Nachteil, den C++-Freunde an Java bemängeln. Die Elemente der Datenstrukturen sind immer vom Typ Object und Typsicherheit über Templates, wie C++ sie bietet, ist bisher nicht vorgesehen. In der nächsten Java-Generationen 1.5 werden generische Typen in die Sprache Einzug halten; ein Compiler mit generischen Typen ist bei Sun verfügbar. Das Vorhaben wird genauer in der Java Specification Requests 14, »Add Generic Types To The JavaTM Programming Language«, beschrieben.
Eine vollständige Kapselung
Um dieNimm-alle-Objekte-auf-Datenstrukturen so anzupassen, dass nur bestimmte Elemente eingefügt und herausgenommen werden dürfen, gibt es mehrere Ansätze. Eine Lösung wäre die interne Benutzung einer allgemeinen Datenstruktur für beliebige Objektreferenzen und die entsprechende Delegation an genau diese Datenstruktur. Etwa für eine verkettete Liste von Socken:
class SockenListe
{
private LinkedList l;
public void add( Socke s )
{
l.add( s );
}
...
}
Diese Technik hat den ungemeinen Vorteil, dass sie wirklich nur Elemente vom Typ Socke akzeptiert, dabei aber auch den Nachteil, dass wir
|
alle Methoden neu implementieren müssen und die Anfragen an die allgemeine Liste delegieren und |
|
dass SockenListe nicht mehr als Liste durchgeht – Collection implementieren macht keinen Sinn, die Typen müssen dann Object sein – und keine der Methoden, etwa von Collections, anwendbar ist. SockenListe hat ja nichts mehr mit den Schnittstellen gemeinsam. |
Durch diese Nachteile lässt sich eine typsichere Liste nicht im großen Stil verwirklichen, insbesondere, da wir viel zu programmieren haben.
Unterklassen bilden
Eine andere einfache Lösung besteht in der Implementierung einer Unterklasse, die dann die kritischen Methoden mit den Eingabe- und Ausgabeparametern implementiert und die alten Methoden mit dem Parameter- beziehungsweise Ergebnis-Typ Object ausschaltet. So kann etwa add() eine UnsupportedOperationException auswerfen, um anzuzeigen, dass Object nicht erlaubt ist. Leider ist die Überprüfung nur auf Laufzeitebene möglich, und dies ist meistens nicht erwünscht.
class SockenListe extends LinkedList
{
public void add( Object o )
{
throw new UnsupportedOperationException( "No add. Only Socks" );
}
public void add( Socke e )
{
super.add( o );
}
}
Eine SockenList ist nun auch eine Form der Liste, genießt somit alle Funktionalität aus der Collection-Klasse. Doch immer noch können beliebige Objekte einem add() übergeben werden. Der Compiler merkt dies nicht; die Rechnung kommt später durch eine Laufzeit-Exception.
|