본문 바로가기
IT

Java Generics-ak Menperatzen: <? extends T> vs <? super T> Komodin (Wildcard) Azterketa Osoa 🧩

by LemonDKel 2025. 10. 11.
반응형

Java Generics-ak Menperatzen: <? extends T> vs <? super T> Komodin Azterketa Osoa

Java-n Generics (Generikoak) erabiltzeak mota-segurtasuna areagotzen du, baina komodin (wildcard) (?) agertzen denean, nahasmena hasi ohi da. Batez ere, goiko muga (extends) eta beheko muga (super) komodinak datuak irakurtzeko (Get) eta idazteko (Put) ekintzekin zuzenean lotuta daude, eta horiek ondo ulertzea ezinbestekoa da.

Artikulu honetan, PECS (Producer Extends, Consumer Super) printzipioan oinarrituta, bi komodin hauen arteko desberdintasunak eta erabilera zuzena argituko ditugu.

1. Zer da Komodina eta Zergatik Behar Dugu?

Generics-etan, komodin batek (?) 'mota ezezaguna' esan nahi du. List<Object> eta List<String> ez dute herentzia-harremanik (hau da, ezin duzu List<String> bat List<Object> batera esleitu). Horregatik, mota generikoak malgutasunez kudeatzeko beharrezkoa da komodina.

2. Goiko Muga: <? extends T> (Irakurtzeko Soilik: Producer)

<? extends T>-k T motakoa edo T-ren ondorengo mota guztiak onartzen dituela esan nahi du. Hemen, T da motaren goiko muga (Upper Bound).

Sailkapena PECS Printzipioa Zeregina (Datu Fluxua) Erabilgarri dauden Metodoak
<? extends T> Producer Extends Datuak sortu (irakurri) soilik egiten ditu. get() edo remove() erabil daitezke, baina add() ez.

📝 Datuak Irakurtzea (Get) Segurua Da:

Imajina dezagun List<? extends Animal> bat dugula. Zerrenda honek Animal objektuak izan ditzake, edo Dog edo Cat bezalako Animal-en azpi-motak.

Zerrendatik objektu bat ateratzen dugunean, gutxienez Animal motako objektu bat dela ziurtatu dezakegu. Hori dela eta, segurtasunez Animal motan jaso dezakegu.

public void printAnimals(List<? extends Animal> list) {
    // Segurtasunez Animal motan irakur daiteke
    Animal animal = list.get(0); 
}

🚫 Datuak Idaztea (Put) Arriskutsua Da:

Baina zerrenda honi Dog objektu berri bat gehitu nahi badiogu, demagun benetako zerrenda List<Cat> zela. Kasu horretan, Dog bat Cat zerrenda batean sartzea litzateke, eta mota-segurtasuna hautsiko litzateke. Horregatik, konpiladoreak add() metodo bidezko idazketa lana blokeatzen du.


3. Beheko Muga: <? super T> (Idazteko Soilik: Consumer)

<? super T>-k T motakoa edo T-ren gaineko mota guztiak onartzen dituela esan nahi du. Hemen, T da motaren beheko muga (Lower Bound).

Sailkapena PECS Printzipioa Zeregina (Datu Fluxua) Erabilgarri dauden Metodoak
<? super T> Consumer Super Datuak kontsumitu (idatzi) soilik egiten ditu. add() erabil daiteke, baina ateratako objektuak T motan jasotzea ez da posible.

✅ Datuak Idaztea (Put) Segurua Da:

Imajina dezagun List<? super Dog> bat dugula. Zerrenda honek, gutxienez, Dog, Animal edo Object bezalako Dog-en gaineko motak eduki ditzakeen zerrenda bat da.

Hona Dog objektu berri bat edo Dog-en azpi-mota bat (adibidez, Puppy) gehitzen badugu, edozein zerrenda motatan (adibidez, List<Animal>, List<Object>) segurtasunez gorde daiteke.

public void addAnimal(List<? super Dog> list) {
    // Dog objektua edo Dog-en azpi-objektuak segurtasunez gehi daitezke
    list.add(new Dog()); 
}

⚠️ Datuak Irakurtzea (Get) Ez Da Argia:

Zerrenda honetatik objektu bat ateratzean, konpiladoreak objektu hori Object motakoa dela ziurta dezake, baina ez daki zehazki Dog edo Animal den. Hori dela eta, segurtasuna bermatzeko, Object motan soilik irakurtzea behartzen du.

public void readAnimal(List<? super Dog> list) {
    // Object motan bakarrik jaso daiteke
    Object obj = list.get(0); 
    // Dog dog = list.get(0); // Konpilazio-errorea!
}

4. Gogoratu PECS Printzipioa

Java Generics-en komodin hauek, azken finean, datuen fluxua (Flow) kontrolatzeko daude. Printzipio hau gogoratzeak komodinen erabileran akatsak saihesten lagunduko dizu:

Printzipioa Gako-hitza Zeregina
PECS Producer Extends Bildumatik datuak atera (irakurri) behar dituzunean (get)
PECS Consumer Super Bilduman datuak sartu (idatzi) behar dituzunean (add)

Kasu gehienetan, metodoen parametroetan List<T>-ren ordez List<? extends T> edo List<? super T> erabiltzeak kodea malguagoa egiten lagunduko dizu.

반응형

댓글