Archief - [PROG]Java Generics

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Rajiv

Legacy Member
Hoi

Ik ben aan het studeren voor mijn scjp, en nu ben ik bezig met generics.
Ik ben een aantal vraagjes hierover aan het oplossen, maar met de volgende zit ik toch wel vast :confused:
Hier is de vraag met de antwoorden:
Code:
Given a method declared as:
 
	public static <E extends Number>List<?super E>process(List<E>nums) 
 
A programmer wants to use this method like this:
 
	/// INSERT DECLARATIONS HERE
 
	output = process(input);
 
Which pairs of declarations could be placed at  /// INSERT DECLARATIONS HERE  to allow
the code to compile? (Choose all that apply.)
 
A.	ArrayList<Integer> input = null;
	ArrayList<Integer> output = null;
 
B.	ArrayList<Integer> input = null;
	List<Integer> output = null;
 
C.	ArrayList<Integer> input = null;
	List<Number> output = null;
 
D.	List<NNmber> input = null;
	ArrayList<Integer> output = null;
 
E.	List<Number> input = null;
	List<Number> output = null;
 
F.	List<Integer> input = null;
	List<Integer> output = null;
 
G.  None of the above.
 

Answer: 
B, E, and F are correct.
The return type of process is definitely declared as List , not an  ArrayList, so  A and D
are wrong. C is wrong because the return type evaluates to List<Integer>, and that can't 
be assigned to a variable of ype  List<Number>. Of course all these would probably cause a 
NullPointerException since the variables are still null —but the question only asked us 
to get the code to compile.
B: ok, Integer = subklasse van Number en returntype List<? super E> klopt ook, superklasse of klasse Integer
E en F ok voor dezelfde redenen, behalve argument voor methode-aanroep verschilt, ArrayList -> List, maar dat is ok hier
Maar wat ik niet snap is waarom C foutief is.
1) Integer is een subklasse van Number
2) returntype List<? super E>, dus de teruggegeven List kan van (of supertype) E zijn. En aangezien E = Integer is, zou volgens mij Number toch ook moeten werken?
Of ben ik hier verkeerd?:confused::confused:

Bavo aka Joske

Legacy Member
Troost u, ik geef intern SCJP cursussen en moest het ook opzoeken :) Het zo gebruiken grenst aan het onleesbare.

Waarom het niet werk is uiteraard logisch: bij generics geldt geen polymorfisme. m.a.w:
List<Integer> lists = new ArrayList<Integer>(); // mag
List<Number> lists = new ArrayList<Integer>(); // mag niet

De types moeten dezelfde zijn.

Dat is wat hier fout gaat, je geeft wel de juiste types mee, en je kan het zelf zo maken dat exact hetzelfde type wordt weergegeven dan wordt verwacht, het is niet gegerandeerd. Wat namelijk wordt weergegeven, is niet perse wat werd meegegeven.

Object is bvb een superklasse van Integer of zelfs Number, maar een lijst van Objecten pas niet in een lijst van Numbers. De methode mag dat volgens de signature wl weergeve, wat niet kan.

Rajiv

Legacy Member
Wat je zegt klopt idd :)
Maar ik heb er eens op gegoogled, en het is blijkbaar een schrijffout in de cursus.
Er staat bij het return-type List<?super E>, maar volgens de auteur moet het List<E> zijn. Hij was wat aan het experimenteren aan de syntax, maar vergat zijn fout aan te passen. En in de errata staat het inderdaad aangepast.

Over die List<? super E> nog een vraagje: klopt dat dat je in een return-variabele geen wildcards mag noteren omdat dit te vaag zou zijn? Ik heb dat eens in een voorbeeldvraag tegengekomen waar men ipv Collection <? extends Number> Collection <E> als return waarde verkoos. Collection <? extends Number> was te vaag stond er bij als uitleg.

Volgens het boek mag je enkel maar Wildcards gebruiken in Reference Variables (en method-argumenten)

Edit: alvast bedankt voor je uiteenzetting :)

Bavo aka Joske

Legacy Member
Wel, dat ligt aan hetzelfde feit, polymorfisme. Als je zegt iets te returnen dat Number extend, kan je dat niet aan iets toewijzen van het type Number, omdat niet zeker is dat de types gaan overeenkomen. Je kan dat dan enkel toewijzen aan een niet-generic List, of rechtsrteeks gebruiken.

Het is wat kloten met Generics daarom. In 90% van de gevallen moet je die zaken niet gebruiken, en kom je ze niet tegen. De SJCP cursus vraagt door op die 10%

Rajiv

Legacy Member
Aha ik snap het thanks :)

Hehe ja dat is inderdaad wel waar wat je zegt. Hetgeen waarvoor het meest gebruik wordt, is voor typed collections. Maar voor de rest...
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan