Wenn wir die !StringBox als Basis nehmen, haben wir bei der Übersetzung der !IntBox in die !StringBox drei Stellen gefunden, an der wir den Typ ändern müssen. Wollen wir die Box in einen generischern Typ umbauen, so müssen wir an den drei Stellen, an denen der konkrete Typ String vorkam, einen Typ-Stellvertreter, eine so genannte Typ-Variable, einsetzen. Der Name der Typ-Variable muss in der Klassendeklaration angegeben werden, denn es kann durchaus mehr als einen Stellvertreter geben. Die Syntax für die generische Typdefinition für unsere Box ist folgende:

<verbatim>
class Box<T> 
{ 
  private T val; 
 
  void setValue( T val ) 
  { 
    this.val = val; 
  } 
 
  T getValue() 
  { 
    return val; 
  } 
}
</verbatim>

An Stelle des konkreten Typs String steht ein formaler Typ-Parameter, in unserem Fall ist das T – die Abkürzung ist oft T, das für Typ steht. Bei generischen Klassen steht die Angabe des Typnamens nur einmal zu Beginn der Klassendeklaration in eckigen Klammern hinter dem Klassennamen. [...]


---++ Wildcards

Ein bewusstes "Vergessen" der Typinformationen lässt sich durch das Wildcard ? erreichen. Es erlaubt aber auch, verschiedene Unterklassen zusammenzuführen. Wir haben schon oben gesehen, dass etwa Folgendes nicht funktioniert:

<verbatim>
Box<Number>  numberBox; 
Box<Integer> bI = new Box<Integer>(); 
Box<Double>  bD = new Box<Double>(); 
numberBox = bI;                           // Compilerfehler Type mismatch
</verbatim>

Über Wildcards ist es jedoch möglich, den Typ von numberBox frei zu lassen. Das ist jetzt aber nicht so gemeint, dass wir die Box gänzlich ohne generische Syntax deklarieren, sondern als:

<verbatim>
Box<?> b;
</verbatim>

Das Fragezeichen in der Angabe steht für alle Boxen und für alle Untertypen T im Fall von Box<T>. Es ist wichtig zu verstehen, dass ? nicht für Object steht, sondern für einen unbekannten Typ!

Da die Wildcards auch mit Typeinschränkung arbeiten, können wir auf diese Weise eine Box von Number-Objekten aufbauen:

<verbatim>
Box<? extends Number> numbersBox; 
Box<Integer> intBox    = new Box<Integer>(); 
Box<Double>  doubleBox = new Box<Double>(); 
Box<String>  stringBox = new Box<String>();
</verbatim>

Die Schreibweise <? extends Klasse> nennt sich upper bound wildcard. (Eine Einschränkung der Art <? super Klasse> heißt lower bound wildcard.) [...]

Für den kompletten Text, siehe (http://www.galileocomputing.de/openbook/javainsel6/javainsel_06_013.htm . )