• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generics question from Exam Lab  RSS feed

 
Treimin Clark
Ranch Hand
Posts: 757
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Following question is from Devaka's Exam Lab (Q.No 29 in Practice-3)

Which of the following statements CANNOT legally insert to the main method independently? (choose one)




Answers:
A. new Letter<A>().getApplication(new Letter<A>());
B. new Letter<B>().getApplication(new Letter<B>());
C. new Letter<C>().getApplication(new Letter<C>());
D. new Letter<B>().getApplication(new Letter<C>());
E. new Letter<C>().getApplication(new Letter<B>());
F. new Letter().getApplication(new Letter());
G. new Letter().getApplication(new Letter<B>());


The correct answer is F

I confused with this; I didn't understand anything about this.
(I've read their explanation, but I didn't understand).

Can someone help me on this?
 
Henry Zhi Lin
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I personally find this annoying as well. It seems no clear method to figure this out. Hope anyone could help us.
 
M Srilatha
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guess the answer should be A. I have tried compiling the program with each stmt given in the answers. And only the statement given in A option is giving compiler error!
Correct me if i am wrong!

Here is the explanation from my side:

A. new Letter<A>().getApplication(new Letter<A>());
//class Letter has type parameter "E extends B". Here A is the super class for B not subclass. So this line wont compile.
B. new Letter<B>().getApplication(new Letter<B>());
//B passes the test for class type parameter "E extends B". And the method getApplication's signature:
public <T extends E> Letter<? super T> getApplication(Letter<? super T> t)
here E is B and assume T as B: B satifies "? super T"

C. new Letter<C>().getApplication(new Letter<C>());
//C is the sub class of B so C passes "E extends B" for class type parameter. And assume T as C: C satifies "? super T"
D. new Letter<B>().getApplication(new Letter<C>());
// B passes the test for class type parameter "E extends B".
And assume T as C: C satifies "T extends B" and "? super T"

E. new Letter<C>().getApplication(new Letter<B>());
//C is the sub class of B so C passes "E extends B" for class type parameter. And assume T as C: B satifies "? super T"
F. new Letter().getApplication(new Letter());
//This will compile with warnings because of not using generics
G. new Letter().getApplication(new Letter<B>());
//This will also compile with warnings!


I know the explanation is not a detailed one.
Hope this helps!
 
Treimin Clark
Ranch Hand
Posts: 757
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, I'm absolutely sorry, the correct answer provided by the simulator is A, sorry for the mistake I made above. :roll:

However, I did not understand the method in the question:




Can anyone explain the behavior of the above method please?
 
Ankit Garg
Sheriff
Posts: 9610
37
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well E here refers to any sub-class of B or the class B itself.

<T extends E> means that T will be a sub-class of E or the same class as E. So if E refers to a sub-class of B(lets say C), then T will refer to C or sub-class of C. If E refers to B, then T will refer to B or a sub-class of B.

Letter<? super T> will take a Letter object which is typed as being a super-class of T or T itself. So now it all depends on what T refers to. If T refers to B, then Letter will be typed as a super class of B or B itself. If T refers to a sub-class of B(lets say C), then Letter will be typed as C or a super-class of C...
 
Treimin Clark
Ranch Hand
Posts: 757
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Ankit, and thanks to Devaka for providing a great exam simulator with great questions for free.
 
Henry Zhi Lin
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can anyone explain to me why the last two chioces are OK?

F. new Letter().getApplication(new Letter());
G. new Letter().getApplication(new Letter<B>());


Why generic code allows legend code works here?

And why the last choice is correct?
 
Ankit Garg
Sheriff
Posts: 9610
37
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry in option F,

F. new Letter().getApplication(new Letter());

you are not providing type to anything. So the compiler would say

"You are not telling me the type of E or T. So Go to hell. I am warning you something wrong could happen"
----------------------------------------------------------------------
G. new Letter().getApplication(new Letter<B> ());

here there is a possibility that the parameter passed to the method is of type B (read my explanation for this). Since no type is provided to new Letter() so the compiler would say

"I don't know the type of E (in class Letter<E extends B> ) , so I don't know the type of T (in <T extends E> ) , so beware, the actual type of the parameter that you are providing might not be B (in new Letter<B> ()). So you are responsible for anything wrong that happens"

As you know generics is only a compile time check so if the compiler thinks that the code is not safe, it warns you and it's up to you to decide what to do. If you continue with the warnings, then you loose the advantage of Generics type safety...
[ November 13, 2008: Message edited by: Ankit Garg ]
 
Henry Zhi Lin
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankit,

thanks for your answer,

G. new Letter().getApplication(new Letter<B> ());

here there is a possibility that the parameter passed to the method is of type B (read my explanation for this). Since no type is provided to new Letter() so the compiler would say

"I don't know the type of E (in class Letter<E extends B> ) , so I don't know the type of T (in <T extends E> ) , so beware, the actual type of the parameter that you are providing might not be B (in new Letter<B> ()). So you are responsible for anything wrong that happens"

As you know generics is only a compile time check so if the compiler thinks that the code is not safe, it warns you and it's up to you to decide what to do. If you continue with the warnings, then you loose the advantage of Generics type safety...

[ November 13, 2008: Message edited by: Ankit Garg ][/QB]


Does this mean

is correct as well?

 
Ankit Garg
Sheriff
Posts: 9610
37
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes Henry! That is also correct. In you example

new Letter<B>().getApplication(new Letter());

compiler knows that E is B (E which is in class Letter<E extends B> ). But you have not provided any type for the parameter passed. So again the compiler will warn you and let you do what you want to do...
 
Henry Zhi Lin
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Same source from exam lab



why this method fail to compile? What the different between the three K in the declaration ?



WHy this fail the compilation?
[ November 13, 2008: Message edited by: Henry Zhi Lin ]
 
Devaka Cooray
Marshal
Posts: 5650
765
Chrome Eclipse IDE Google App Engine IntelliJ IDE jQuery Postgres Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm sorry to here that explanation on my simulator is not so helpful.

Thanks for everyone for discussing it in this topic.
 
Ankit Garg
Sheriff
Posts: 9610
37
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry the first code doesn't compile as you are redeclaring K in the method. Although I am not sure about it. Try this modified code



The second one has a more obvious reason for not compiling. An object of class BB can be typed only with a sub-class of Number. In the method, you are declaring that V is a sub-class of Character and the method returns an instance of BB which is of type V which is not allowed as a type which V represents cannot be a sub-type of both Number and Character.

This code will work

 
suresh pilakal babu
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
new Letter<B>().getApplication(new Letter<C>());

Hoe the test "E extends B" will pass here?

Here E is B, then it will become "B extends B".
"B extends B" is cyclic inheritance .right?
 
Ankit Garg
Sheriff
Posts: 9610
37
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by suresh pilakal babu:
new Letter<B>().getApplication(new Letter<C>());

Hoe the test "E extends B" will pass here?

Here E is B, then it will become "B extends B".
"B extends B" is cyclic inheritance .right?


No suresh, when you write <E extends B> it doesn't mean that you are inheriting from a class. It's just a check that the type that you pass passes instanceof operation on B i.e. it is class B or a sub class of B.

eg List<T extends Integer> list = new ArrayList<Integer>();

here the list will accept a List which is of type Integer or it's sub types...
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!