aspose file tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generic Method from K&B Master Exam Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Reply Bookmark "Generic Method from K&B Master Exam" Watch "Generic Method from K&B Master Exam" New topic
Author

Generic Method from K&B Master Exam

Welly Tambunan
Ranch Hand

Joined: Aug 18, 2008
Posts: 40
The source is from K&B Master Exam and some modification of mine.



The first code is work. But why the next one is failed to compile??




Based on my experiment i think that the return value decide what the type of T. In this case it must be Object.
So i draw the conclusion that the parameter accept List<? extends Object>. But the compiler said that the List<Object> is required.

Could somebody please help me?
How the return value and the parameter is related ?
Steven Landers
Ranch Hand

Joined: Nov 02, 2008
Posts: 30
This is sometimes rather tricky. Keep in mind if you have a <? extends T> in your argument, then T will actually be set to whatever the element type of input is - throughout the entire method signature. On the other hand, if you use <? extends Object> your second example will work.

The compiler error is caused because Polymorphism does not apply to elements of collections when assigning a collection object to a collection reference.

i.e. So this is illegal
List<Object> myList = new ArrayList<Integer>();

...and this is legal:
List<Integer> myList = new ArrayList<Integer>();

When we call backwards() and pass 'input' as the parameter, we're setting T to the type 'Integer' throughout the ENTIRE method signature:


This returns a List<Integer> collection, which CANNOT be assigned to a List<Object> collection. If we were to pass a List<Number> object, then T would represent Number...which could not be assigned to either a List<Object> or a List<Integer> collection.

In the argument, if you change T to Object....it works! Why? This is because T is then set to Object, and ? has no effect on it.

Here's how to do precisely what you want:


This forces the arguments element type to extend T - via the generic type declaration K. This returns a type of List<Number> because the user's declared variable is of type List<Number>. If T existed in the argument, then the passed element type would override the T.

Hopefully that didn't confuse anyone further. Eclipse allows one to hover over a given method call like backwards(input) and see how the method signature is interpreted with generics. I'd recommend using Eclipse to help with various 'what if' scenarios.

Good luck!
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
You can also explicitly require the generic method to use a specific type:



All code in my posts, unless a source is explicitly mentioned, is my own.
Welly Tambunan
Ranch Hand

Joined: Aug 18, 2008
Posts: 40
Thank you Steven and Ruben,

So the parameter decide the T. How about this one. Is that the same thing happen when i use the super keyword?



The code above is successfully compiled. And i can change the String to whatever type and that still succesfully compile.
Could you help me again please?
Ryan Beckett
Ranch Hand

Joined: Feb 22, 2009
Posts: 192
That code didn't compile for me. I didn't know you can bound types to methods. Your the man Ruben!
Steven Landers
Ranch Hand

Joined: Nov 02, 2008
Posts: 30
For me, that code didn't seem to complile. It's the same issue as before, as we can't set a List<Integer> to a List<Object>. The return value of backwards is Integer due to the argument's setting of the T type.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Ryan Beckett wrote:That code didn't compile for me. I didn't know you can bound types to methods. Your the man Ruben!

Clint Eastwood is the man. I'm just a man.
Jokes aside, I didn't know that either until I read it somewhere. The idea is that most often the compiler can figure out the type based on the argument type at the type of the invocation. But sometimes several types could fit, like in this case, so you can provide the compiler some extra information to make it work the way you want it to.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
The code is compiling for me. I don't understand very well how it's working though, because the return type must be List<String>, which means that T must be resolved to String, but then List<Integer> can't be assigned to List<? super String>. This is an interesting question, and I'd also like to know what's going on.
Steven Landers
Ranch Hand

Joined: Nov 02, 2008
Posts: 30


I'd be interested to know how it would compile elsewhere. Of course, one could change this code to make it compile - or perhaps import some non-standard Integer and String classes to let them share a hierarchy ;)
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Steven, can you try compiling from the command line using javac?
Welly Tambunan
Ranch Hand

Joined: Aug 18, 2008
Posts: 40
Ruben Soto wrote:Steven, can you try compiling from the command line using javac?


Yes, that's working in my machine with javac command. But i try to use eclipse and that's give me an error.
Is eclipse using the different javac compiler?
Steven Landers
Ranch Hand

Joined: Nov 02, 2008
Posts: 30
I'm stumped. It works fine from javac - how the heck? Eclipse is pointing to a 1.6.0_03 and my javac is pointing to a 1.6.0_05 installation. I would like to think they would be similar The classes are all the java.util classes - nothing crazy there.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Yes, Eclipse uses a proprietary compiler which does not always behave like javac. Someone recently claimed that you can specify a given compiler in Eclipse per project though. I recommend to not use Eclipse at all if you are preparing for the SCJP though.
 
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to run our stuff on 16 servers instead of 3.
 
subject: Generic Method from K&B Master Exam
 
Similar Threads
Generics
Generic method question
How to Call Generic Method
Solution needed for Generics Question
K & B Mock exam Generics doubt