• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Solution needed for Generics Question

 
Balraj Momi
Ranch Hand
Posts: 45
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can someone please tell me that how come D is one of the answers in following question?


Which of the following can be inserted at // INSERT HERE to compile and run without error?
A. public static <T> List <T> backwards(List<T> input)
B. public static <T> List <T> backwards(List<? extends T> input)
C. public static <T> List <T> backwards(List<? super T> input)
D. public static <T> List <? extends T> backwards(List<T> input)
E. public static <T> List <? super T> backwards(List<T> input)
F. public static <? extends T> List <T> backwards(List<T> input)
G. public static <? super T> List <T> backwards(List<T> input)


I could tell that A,B,E are correct options, but not able to figure out how D is correct.

Any help would be appreciated

Regards
Balraj
 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
F and G the Boundry specifications are wrong.

C You can take any T or supertype of T but return only T....hmm then what will happen to the supertype if passed.

D You can take T and return any subtype of T..... valid because T can contain objects of the subtype....(Animal has Dog,Cat)

A Correct with normal syntax n boundry

B You can take any subtype of T and return as T..... Subtype is a T - Pass

E You can take T and return T and Supertype of T......T is a subtype of Supertype of T (Same as B) - Pass

Hope You understand.....u can substitute T -> Animal and subtypes of Animal can be DOg Cat and Wolf...

Cheers.
 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
D

Because Say Animal Arraylist can containg dog,cat objects so you can pass an animal and then in the method can return something that extends Animal. say cat.... which on returning to the main method can be used by the cat reference variable without the cast..
 
Ankit Garg
Sheriff
Posts: 9521
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Balraj can you please Quote Your Sources...
 
Balraj Momi
Ranch Hand
Posts: 45
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankit,
Sorry this was my first post so didn't know what exactly to do.
Actually this question is from Master Exam that comes with SCJP 5 by Kathy Sierra/Bert Bates..

Nitish
Thanks for your reply. I thought the same as you. But when I tried to compile it, It did not work for me. Line 1 gave me problems.
This is what I have tried, Please tell me If I did something wrong here



Regards
Balraj
 
Henry Wong
author
Marshal
Pie
Posts: 21221
81
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But when I tried to compile it, It did not work for me. Line 1 gave me problems.


The problem at line 1 is not related to the method -- the method should compile fine.

The problem is the assignment. You are trying to assign a List<? extends Number> object to a List<Integer> reference -- which is not allowed.

Henry
 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The thing here is What quarantee you have the the thing you return will alwayz be an Integer.....Actually these things with generics are checked in compile time as JVM has nothing for generics....

here input is <Integer> and you are assigning <something that extends Number> to output. to you have any guarantee that it will alwayz be an Integer.

use a variable List<Number> output to take in the returned value.
 
Balraj Momi
Ranch Hand
Posts: 45
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot Nitish and Henry for your help. I understood it well.
 
michael muris
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had the same problem as the OP.

Could someone explain the value of making the return type <? extends T> instead of <T>, given that, as henry has explained, it is not legal to assign a List<? extends Number> to a List<Integer> ?

It seems then there is really no exploitable difference between:

(answer D)
and
(answer A)

 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
D has a more broader prospect thats all. In A you can only pass T= Animal,nothing else.You cannot pass Dog ,Cat, Wolf which are sub classes of Animal. If you try to pass a sub class of T then compiler will complain.

In D you can pass anything which is a subclass of T(Dog, cat,wolf) n the compiler will not complain. The only thing need to take care is you cannot add any thing to the list if you pass a sub class i.e in <? extends T> because then the compiler will complain.
If we want to add then <? super T> should be used but then here also T should be a subclass and the list that is passed should be <supertype of T>
 
michael muris
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Nitish: The difference between D and A is in the declared type of the return value. In both cases I believe I can add anything that implements T to the returned array.
Can you provide an example of something that is possible with the D answer but not with the A answer?
 
Henry Wong
author
Marshal
Pie
Posts: 21221
81
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
michael muris wrote:@Nitish: The difference between D and A is in the declared type of the return value. In both cases I believe I can add anything that implements T to the returned array.
Can you provide an example of something that is possible with the D answer but not with the A answer?


I am not sure if this is the correct way to think about it -- there is really no reason to return a bounded type, if it is possible to specify exactly what you want to return.

But what if you can't specify exactly what you are going to return? What if, given a type T, the best you can do is return some type that is of something that extends T?

Henry
 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry muris......i took up the generic passing contract.....

But see in A.....you have an Animal List.....Animal class is extended by Dog and Cat. So in A you can add and return only animal. And yes in the called method it should be taken in by the <Animal> variable only.

In D you can pass an Animal List and in the method can add anything which is a Dog or a Cat and you can return Dog or Cat also.Cause it can return anything that extends Animal. But in the called method it should be taken in by the <Animal> variable only because you really cannot be sure which subtype is going to come out when you say <? extends Animal>.... Atleast the compiler wont be sure.
 
Stephen Davies
Ranch Hand
Posts: 352
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm! Generics are certainly a tricky sort.

My Understanding of Michael's question is this:

If one generically declares return type <T> to a method, then that is exactly what must be returned.
I was under the impression that polymorphic covariant returns must be explicitly declared in generics.
This means that if you wish to return a covariant ('is a' ) object of the declared <T> one
must add <? extends T> (upper bounds) declaration. In an example, the following should apply (in my interpretation).



However, where I become foggy is in the parameter passing and manipulation area in regards to bounds. Here is my current
understanding, anyone feel free to jump in ans correct me at any time!






 
Nitish Bangera
Ranch Hand
Posts: 537
Eclipse IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
public static <T> List <T> backwards(List<? super T> input)

in this yes normally with void return type you can add or remove. Also when the list you are passing as an Argument is a super of T. That is Animal is the list you are passing and accepting parameter is List<? super Dog> input. o k understood.

But if you accept Animal i.e <? super Dog> within the method T => Dog, there is no way you can add it to the List<T> (List<Dog>) and then return as List<T>
 
Stephen Davies
Ranch Hand
Posts: 352
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
..Yes, the returning for me I must read up on. Ignoring the return for now however, if you follow the lower bounds argument here:
replacing Type T with Dog, and assuming Dog extends (or implements) Animal, and of course, implicitly Object:




So in each of these cases the compiler reads ok the reference types in this list can be a Dog or higher, so
at a minimum (lower bound) the list will be a Dog, and that's fine as that's the Type declared, so feel free to add / remove
from the List.

However the return type of the method, is a different matter, I would suppose if you were to return a List it must be a list of Dogs, here I am foggy, however in this case I am simply talking of the argument type, NOT the return type.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic