Sobes.tech
Middle+

Ce este principiul PECS și cum se aplică în Java?

sobes.tech AI

Răspuns de la AI

Principiul PECS (Producer Extends Consumer Super) este o regulă mnemonică pentru a determina când să folosiți cuvintele cheie extends și super atunci când lucrați cu tipuri wildcard în genericele Java.

  • Producător (Producer): Când utilizați un parametru generic pentru obținerea de date (extrageți elemente dintr-o colecție), folosiți wildcard cu extends. Colecția acționează ca un producător de date. Tipul ? extends T înseamnă "orice tip care este T sau o subclasă a sa". Puteți citi elemente în siguranță ca tip T (sau superclasa sa), dar nu puteți adăuga elemente într-o astfel de colecție (cu excepția null).

  • Consumator (Consumer): Când utilizați un parametru generic pentru adăugarea de date (puneți elemente într-o colecție), folosiți wildcard cu super. Colecția acționează ca un consumator de date. Tipul ? super T înseamnă "orice tip care este T sau o superclasă a sa". Puteți adăuga în siguranță elemente de tip T (sau subclasele sale) într-o astfel de colecție, dar la citire veți obține elementele ca Object.

Aplicare în Java:

Se folosește cu tipuri wildcard (?) pentru a crește flexibilitatea API-urilor care lucrează cu colecții sau alte tipuri generice, permițându-le să funcționeze cu un spectru mai larg de tipuri, păstrând în același timp siguranța tipurilor.

Exemple:

// Exemplu Producer
// Metoda printAll citește dintr-o List
public void printAll(List<? extends Number> list) {
    // Putem citi elemente ca Number (sau Object)
    for (Number num : list) {
        System.out.println(num);
    }
    // Nu putem adăuga elemente (cu excepția null)
    // list.add(123); // Eroare de compilare
}

// Exemplu Consumer
// Metoda addNumbers adaugă în List
public void addNumbers(List<? super Integer> list) {
    // Putem adăuga Integer sau subclasele sale
    list.add(1);
    list.add(new Integer(2));
    // list.add(new Double(3.0)); // Eroare de compilare

    // La citire, obținem Object
    Object o = list.get(0);
}