Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Generics in Java

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){

...

}

while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: Generics in Java

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.
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
Xenion
Artikelen: 0
Berichten: 2.609
Lid geworden op: za 21 jun 2008, 10:41

Re: Generics in Java

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.
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: Generics in Java

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?
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
Xenion
Artikelen: 0
Berichten: 2.609
Lid geworden op: za 21 jun 2008, 10:41

Re: Generics in Java

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.
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: Generics in Java

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.
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
physicalattraction
Moderator
Artikelen: 0
Berichten: 4.164
Lid geworden op: do 30 mar 2006, 15:37

Re: Generics in Java

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.

Terug naar “Informatica en programmeren”