Programmieren_2/generics2.md

2.6 KiB

Generizität


Grundlagen

Durch Generizität können wir Typen, Klasse und Methode parametrisieren. Der genutzte Typ wird dann zur Laufzeit übergeben.

Genutzt wird dieses Sprachkonzept z.B. im Collection Framework.

// Deklaration
class Test<T> {
    public T gibHer(T type) { return type; }
}
// Benutzung
Test<String> test;
String result = test.gibHer(test);

Raw Types

Der Java-Compiler entfernt alle generischen Parameter und arbeitet dann auf den Raw Types. Dieser Vorgang wird Type Erasure genannt. Das führt zu Beschränkungen zur Laufzeit:

  • Generische Klassen können keine statischen Felder haben
  • Es können keine Instanzen aus generischen Typen erzeugt werden
  • Es kann kein instanceof für generische Typen genutzt werden
  • ... (vollständige Liste auf der Java-Website)

Subtyping und Vererbung

Stehen zwei Typen in einer Subtyp-Beziehung (class Dreieck extends Form) bedeutet das nicht, dass auch die parametrisierten Typen in einer Verbindung stehen.

// Deklaration
class FlaechenVerarbeiter {
    public void verarbeiteFlaechen(List<Form> liste) {
}
// Benutzung
Dreieck dreieck = new Dreieck();
Verarbeiter verarbeiter = new Verarbeiter();
verarbeiter.verarbeiteFlaechen(dreieck); // Geht das?

Wildcards

Werden genutzt um beliebige generische Type als Parameter, Feld, lokale Variable oder Rückgabetypen zu deklarieren.

Benutzt wird dieses Sprachkonzept wenn man z.B. auf Collections arbeiten will:

class ListenSchreiber {
    public void schreib(List<?> liste) {
      for (Object elem: list) {
           System.out.println(elem);
      } 
    }
}

Lower Bounds

Beschränkt den Wildcard Typen nach unten. Dafür wird das Schlüsselwort super verwendet.

// Hierarchie Object -> Number -> Integer
class IntegerSammler {
    public void schreib(List<? super Integer> liste) {
      for (int i = 0; i <= 10; i++) {
           System.out.println(i);
      } 
    }
}

Upper Bounds

Beschränkt den Wildcard Typen nach oben. Dafür wird das Schlüsselwort extends verwendet.

// Hierarchie Object -> Number -> Integer
//                             -> Double
class Sortierer {
  public void sortiere(List<? extends Number> liste) {
    // Ein cleverer Sortieralgorithmus,
    // der mit Vergleichoperatoren funktioniert.
  }
}

Aufgaben