Generics, Autoboxing, Subtyping

Die im vorhergehenden Beispiel benutzte Klasse kann aber auch als aktuellen Parameter eine abstrakte Klasse wie Number verwenden:

Mit Hilfe des Java Autoboxing kann man die Variablen k3 und k4 auch wie folgt belegen:

Koordinate<Number> k3 = new Koordinate<Number>(2l, 3l);
System.out.println(k3);

k3 = new Koordinate<Number>(4.4f, 5.5f);
System.out.println(k3);

Die Variable k3 hat den formalen Parametertyp Number.  Die aktuellen Parameter 21 und 31 sind int Typen. Sie werden automatisch in Instanzen von Integer umgewandelt und sind daher Spezialisierungen der Klasse Number. Die Variable k3 zeigt hier zuerst auf eine Koordinate die aus ganzen Zahlen besteht und anschließend auf eine Koordinate die aus Fließkommanzahlen bestehen

Ohne Autoboxing würde man die Variable k3 so belegen:

Koordinate<Number> k3 = new Koordinate<Number>(new Integer(2l), new Integer(3l));

Subtyping

Die parametrisierte Klasse Koordinate<Number> kann zwar wahlweise auf verschiedene Varianten von Objekten zugreifen die parametrisiert mit Koordinate<Number> erzeugt wurden. Sie kann aber nicht auf Objekte gleichen Inhalts aus Koordinate<Integer> zugreifen. Das folgende Implementierungsbeispiel erlaubt nicht die letzte Zuweisung von k2 auf k3:

Koordinate<Double>  k1 = new Koordinate<Double>(2.2d, 3.3d);
Koordinate<Integer> k2 = new Koordinate<Integer>(2, 3);
Koordinate<Number>  k3 = new Koordinate<Number>(2l, 3l);
                    k3 = new Koordinate<Number>(4.4f, 5.5f);
                    k3 = k2; // Fehler

Die Vererbungsbeziehung besteht nicht zwischen den generischen Klassen selbst. Der Javaübersetzer erzeugt den folgenden Fehler:

found   : Kurs2.Generics.Koordinate<java.lang.Integer>
required: Kurs2.Generics.Koordinate<java.lang.Number>
        k3 = k2;

In diesem Beispiel wird das "Liskov Substitution Principle" verletzt! Der Übersetzer javac erkennt diese Fehler und übersetzt diesen Quellcode nicht.