Sobes.tech
Middle+

Mi az a PECS elv és hogyan alkalmazzák Java-ban?

sobes.tech MI

Válasz az MI-től

A PECS (Producer Extends Consumer Super) elv az emlékezetes szabály arra, hogy meghatározza, mikor kell a extends és super kulcsszavakat használni a Java generikusok wildcard típusainál.

  • Producer (Gyártó): Ha egy generikus paramétert arra használsz, hogy adatokat szerezzen (elemeket vonjon ki egy gyűjteményből), akkor használj wildcard-ot extends-szel. A gyűjtemény adatgyártóként működik. A ? extends T típus azt jelenti, hogy "bármilyen típus, ami T vagy annak alosztálya". Biztonságosan olvashatsz elemeket T típusban (vagy annak szuperosztályában), de nem adhatsz hozzá elemeket ilyen gyűjteményhez (kivéve a null-t).

  • Consumer (Fogyasztó): Ha egy generikus paramétert arra használsz, hogy adatokat adjon hozzá (elemeket tegyen egy gyűjteménybe), akkor használj wildcard-ot super-rel. A gyűjtemény adatfogyasztóként működik. A ? super T típus azt jelenti, hogy "bármilyen típus, ami T vagy annak szuperosztálya". Biztonságosan hozzáadhatsz T típusú (vagy alosztályú) elemeket, de olvasáskor Object-ként kapod őket.

Java-ban való alkalmazás:

Wildcard típusokkal (?) használva növeli az API-k rugalmasságát, amelyek gyűjteményekkel vagy más generikus típusokkal dolgoznak, lehetővé téve számukra, hogy szélesebb típusskálával működjenek, miközben megőrzik a típusbiztonságot.

Példák:

// Producer példa
// A printAll metódus List-ből olvas
public void printAll(List<? extends Number> list) {
    // Elemeket Number-ként (vagy Object-ként) olvashatunk
    for (Number num : list) {
        System.out.println(num);
    }
    // Nem adhatunk hozzá elemeket (kivéve null)
    // list.add(123); // Fordítási hiba
}

// Consumer példa
// Az addNumbers metódus List-be ad hozzá
public void addNumbers(List<? super Integer> list) {
    // Integer vagy alosztályai hozzáadhatók
    list.add(1);
    list.add(new Integer(2));
    // list.add(new Double(3.0)); // Fordítási hiba

    // Olvasáskor Object-et kapunk
    Object o = list.get(0);
}