1 van 1

Generics in Java

Geplaatst: do 02 jan 2014, 15:20
door Math-E-Mad-X
Ik heb deze tutorial over Generics in Java gelezen:

http://docs.oracle.c...rics/index.html

Maar er is één ding dat ik nog niet begrijp: is er een verschil, en zo ja, wat is het verschil, tussen de volgende twee functie declaraties:

Code: Selecteer alles


<T extends Number> void foo1(ArrayList<T> list){

...

}

void foo2 (ArrayList<? extends Number> list){

...

}


Re: Generics in Java

Geplaatst: do 02 jan 2014, 15:50
door Math-E-Mad-X
Na wat googlen ben ik er inmiddels achter dat de eerste implementatie als voordeel heeft dat je naar het type T binnenin de functie kunt refereren. Bijvoorbeeld:

Code: Selecteer alles


<T extends Number> void foo1(ArrayList<T> list){

T firstElem = list.get(0);

 ...

}

Dit is met de tweede functie declaratie duidelijk onmogelijk. Maar wat ik dan nog niet begrijp is waarom je dan niet gewoon altijd de eerste declaratie zou gebruiken. Het feit dat de tweede declaratie ook mogelijk is lijkt toch te suggereren dat er situaties zijn waarbij die de voorkeur heeft boven de eerste declaratie.

Re: Generics in Java

Geplaatst: do 02 jan 2014, 17:53
door Xenion
Volgens mij is de 2de declaratie beter omdat die algemener is. Je kan foo2 aanroepen voor eender welke Arraylist, zonder at compile-time te moeten weten welk type T er in die list zal zitten.

Als je echt expliciet objecten van het type T moet manipuleren in de functie zelf, dan heb je wel de eerste declaratie nodig.

Re: Generics in Java

Geplaatst: vr 03 jan 2014, 00:22
door Math-E-Mad-X
Xenion schreef: do 02 jan 2014, 17:53
Volgens mij is de 2de declaratie beter omdat die algemener is. Je kan foo2 aanroepen voor eender welke Arraylist, zonder at compile-time te moeten weten welk type T er in die list zal zitten.
Sorry, ik snap deze uitleg niet. Waarom zou je moeten weten welk type T er in de list zit? Als je die functie foo1 aanroept dan werkt hij toch gewoon voor iedere ArrayList list van objecten die Number extenden? Precies hetzelfde als foo2 zou ik zeggen.

Zou je een expliciet voorbeeld kunnen geven?

Re: Generics in Java

Geplaatst: vr 03 jan 2014, 12:10
door Xenion
Je hebt gelijk, het is geen kwestie van beter of slechter. Ik werk zelf gewoonlijk in C++ en daar is dat allemaal anders :P

Het verschil zit hem in hoe je functie ineen zit.

In foo2 maakt het niet uit wat er in de ArrayList zit. foo2 zal nooit expliciet de objecten erin manipuleren en hoeft dus het type niet te kennen en daar kan je dus gewoon die wildcard '?' gebruiken.

In sommige functies is het echter belangrijk dat je echt een functietype hebt omdat je misschien binnen foo1 nog andere generische functies op dat zelfde type moet uitvoeren of omdat je een element van dat type wil teruggeven.

Een eenvoudig voorbeeld is een functie die het grootste element van die arraylist moet teruggeven. Dat zou dan iets zijn als:

Code: Selecteer alles


public <T extends Comparable> T findLargest( ArrayList<T> l)

{

  l.sort();

  return l[0];

}

(pseudocode want ik gebruik nooit Java)

Hier moet het type T bekend zijn voor de functie findLargest omdat T zowel het type is van de elementen in de arraylist als het return type.

Lees ook vanaf "One question that arises is: when should I use generic methods, and when should I use wildcard types?" op deze pagina.

Re: Generics in Java

Geplaatst: vr 03 jan 2014, 17:17
door Math-E-Mad-X
Xenion schreef: vr 03 jan 2014, 12:10
Lees ook vanaf "One question that arises is: when should I use generic methods, and when should I use wildcard types?" op deze pagina.
Ah, bedankt, dit stukje geeft precies het antwoord wat ik zocht. In feite komt het allemaal hier op neer:
Using wildcards is clearer and more concise than declaring explicit type parameters, and should therefore be preferred whenever possible.

Wildcards also have the advantage that they can be used outside of method signatures, as the types of fields, local variables and arrays.

Re: Generics in Java

Geplaatst: wo 19 feb 2014, 12:39
door physicalattraction
Using wildcards is clearer and more concise than declaring explicit type parameters, and should therefore be preferred whenever possible.
Dat is natuurlijk subjectief. Ik vind die eerste declaratie duidelijker.