- Joker (Java)
-
Der Joker (oder Wildcard)
?
ist in Java ein spezieller aktueller Typparameter für die Instanziierung generischer (parametrisierter) Typen. In diesem Artikel werden die wichtigsten Regeln für seine Verwendung zusammengefasst.Inhaltsverzeichnis
Kovarianz für generische Typen
Im Gegensatz zu Arrays (die in Java kovariant sind) sind unterschiedliche Instanziierungen eines generischen Typs untereinander nicht (auch nicht explizit) kompatibel: Nach den Vereinbarungen
Generisch<Obertyp> oberGenerisch; Generisch<Untertyp> unterGenerisch;
meldet der Compiler bei beiden Konvertierungen (castings)(Generisch<Untertyp>)oberGenerisch
und(Generisch<Obertyp>)unterGenerisch
einen Fehler.Diese Inkompatibilität kann mit dem Joker aufgeweicht werden, wenn
?
für einen aktuellen Typparameter eingesetzt wird:Generisch<?>
ist der abstrakter Obertyp aller Instanziierungen des generischen Typs. Das heißt, von diesem Typ können nur Referenzen, keine Objekte gebildet werden. Der Sinn einer solcher Referenz ist, dass zu ihr beliebige Instanziierungen vonGenerisch
passen.Joker als Parametertyp
Im Rumpf der generischen Einheit wird der Typparameter wie die obere Schranke (wenn uneingeschränkt, dann wie
Object
) gehandhabt. Wenn der Ergebnistyp (return type) einer Funktion der Typparameter ist, kann das Ergebnis (z.B. vom Typ?
) in eine Referenz vom Typ der Schranke (Object
, wenn keine Schranke) übernommen werden. In die andere Richtung, zum Joker-Typ passt kein anderer Typ, nicht einmalObject
: Wenn?
für den Typ des formalen Parameters einer Methode eingesetzt wurde, können ihr keine aktuellen Parameter übergeben werden. Sie kann dann nur nach Konvertierung (casting) der Joker-Referenz aufgerufen werden:class Generisch<T extends Schranke> { private T t; void schreiben(T t) { this.t = t; } T lesen() { return t; } } ... Generisch<?> jokerReferenz; Schranke o = jokerReferenz.lesen(); // Object wäre auch OK jokerReferenz.schreiben(new Object()); // Typfehler ((Generisch<Schranke>)jokerReferenz).schreiben(new Schranke()); // OK
Einschränkung des Jokers
Nicht nur der formale Typparameter, auch der Joker kann (weiter) von oben eingeschränkt werden, wenn man nicht beliebige Instanziierungen kompatibel halten möchte:
Generisch<? extends UntertypVonSchranke> vonObenEingeschränkteReferenz;
In diese Referenz kann nun eine Instanz von
Generisch
eingehängt werden, wo der aktuelle Typparameter ein Untertyp vonUntertypVonSchranke
ist. In eine Einschränkung von untenGenerisch<? super UntertypVonSchranke> vonUntenEingeschränkteReferenz;
können Instanziierungen von
Generisch
mit einem beliebigen Obertyp (z.B.Schranke
) vonUntertypVonSchranke
eingehängt werden. Es ist also möglich, dass die zugelassenen Typen von zwei Seiten eingeschränkt werden: von oben durch die Klassenvereinbarung (extends Schranke
), von unten durch die Referenzvereinbarung (super UntertypVonSchranke
).Objekterzeugung mit Joker-Instanziierungen
Obwohl von Joker-Instanziierungen keine Objekte erzeugt werden können (
new Generisch<?>()
ist also verboten, weilGenerisch<?>
abstrakt ist), können Array-Objekte nur von uneingeschränkten Joker-Instanziierungen (also von keinen anderen generischen Instanziierungen) erzeugt werden:new Generisch<?>[20]
ist korrekt, währendnew Generisch<Schranke>[20]
ist verboten.Referenzen
- The Java Language Specification, Third Edition (Sun), ISBN 978-0-321-24678-3
- Java Tutorials, Lesson Generics http://download.oracle.com/javase/tutorial/java/generics/index.html
- Typkompatibilität in Java http://public.beuth-hochschule.de/~solymosi/veroeff/typkompatibilitaet/Typkompatibilitaet.html#Joker
Wikimedia Foundation.