Sobes.tech
Middle+

Was ist das PECS-Prinzip und wie wird es in Java angewendet?

sobes.tech KI

Antwort von AI

Das PECS-Prinzip (Producer Extends Consumer Super) ist eine Eselsbrücke, um zu bestimmen, wann die Schlüsselwörter extends und super beim Arbeiten mit Wildcard-Typen in Java-Generics zu verwenden sind.

  • Producer (Erzeuger): Wenn du einen generischen Parameter verwendest, um Daten zu erhalten (Elemente aus einer Sammlung extrahieren), verwende Wildcards mit extends. Die Sammlung fungiert als Datenproduzent. Der Typ ? extends T bedeutet "jeder Typ, der T oder eine Unterklasse davon ist". Du kannst Elemente sicher als Typ T (oder seine Oberklasse) lesen, aber keine Elemente zu einer solchen Sammlung hinzufügen (außer null).

  • Consumer (Verbraucher): Wenn du einen generischen Parameter verwendest, um Daten hinzuzufügen (Elemente in eine Sammlung einzufügen), verwende Wildcards mit super. Die Sammlung fungiert als Datenverbraucher. Der Typ ? super T bedeutet "jeder Typ, der T oder eine Oberklasse davon ist". Du kannst sicher Elemente vom Typ T (oder seine Unterklassen) zu einer solchen Sammlung hinzufügen, beim Lesen erhältst du sie jedoch als Object.

Anwendung in Java:

Wird mit Wildcard-Typen (?) verwendet, um die Flexibilität von APIs zu erhöhen, die mit Sammlungen oder anderen generischen Typen arbeiten, sodass sie mit einem breiteren Spektrum an Typen funktionieren, während die Typsicherheit gewahrt bleibt.

Beispiele:

// Beispiel Producer
// Die Methode printAll liest aus einer List
public void printAll(List<? extends Number> list) {
    // Elemente können als Number (oder Object) gelesen werden
    for (Number num : list) {
        System.out.println(num);
    }
    // Elemente können nicht hinzugefügt werden (außer null)
    // list.add(123); // Kompilierungsfehler
}

// Beispiel Consumer
// Die Methode addNumbers fügt einer List Elemente hinzu
public void addNumbers(List<? super Integer> list) {
    // Es können Integer oder seine Unterklassen hinzugefügt werden
    list.add(1);
    list.add(new Integer(2));
    // list.add(new Double(3.0)); // Kompilierungsfehler

    // Beim Lesen erhält man Object
    Object o = list.get(0);
}