Sobes.tech
Middle

Welche Möglichkeiten gibt es bei Generics?

sobes.tech KI

Antwort von AI

Generics ermöglichen die Erstellung parametrischer Klassen, Schnittstellen und Methoden.

Hauptfunktionen:

  • Code-Wiederverwendung: Erstellung universeller Datenstrukturen und Algorithmen, die mit beliebigen Typen funktionieren.
  • Typensicherheit zur Kompilierungszeit: Typfehler werden zur Compile-Zeit erkannt, nicht zur Laufzeit. Entfernt die Notwendigkeit manueller Typumwandlungen und potenzieller Fehler ClassCastException.
  • Verbesserte Lesbarkeit: Der Code wird verständlicher, da er explizit angibt, mit welchen Typen er arbeitet.

Beispiele:

  • Die Container-Klasse List<T> kann Elemente beliebigen Typs T speichern.
  • Die Methode static <T> T getFirst(List<T> list) kann das erste Element einer beliebigen Listentyp zurückgeben.

Einschränkungen bei Generics:

  • Es ist nicht möglich, Instanzen von generischen Typen zu erstellen: new T().
  • Primitive Typen können nicht als Typparameter verwendet werden (z.B. List<int> - falsch, stattdessen List<Integer> verwenden).
  • Arrays von generischen Typen können nicht direkt erstellt werden (z.B. T[] array = new T[10] - falsch, stattdessen ArrayList verwenden oder casten).
  • Statische Felder von generischen Typen können nicht direkt verwendet werden.
  • Typinformationen werden zur Laufzeit gelöscht (Type Erasure), außer bei bounded Wildcards.

Wildcards und begrenzte Typparameter:

  • <?>: Unbekannter Typ. Ermöglicht das Lesen von Elementen, aber nicht das Schreiben.
  • <? extends T>: Obergrenze. Ermöglicht die Arbeit mit Typen, die Untertypen von T sind. Es können Elemente vom Typ T oder seinen Supertypen gelesen werden, aber nicht geschrieben (außer null).
  • <? super T>: Untergrenze. Ermöglicht die Arbeit mit Typen, die Supertypen von T sind. Es können Elemente vom Typ T oder seinen Subtypen geschrieben werden, beim Lesen ist nur Object zugänglich.

Beispiel:

// Methode, die Elemente aus beliebiger Liste mit Subtypen von Number ausgeben kann
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Kompilierungsfehler
}

// Methode, die Integer in eine Liste hinzufügen kann,
// die Integer oder deren Supertypen enthält
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Kompilierungsfehler, gibt Object zurück
}