GeeCON Prague 2014*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generic question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generic question" Watch "Generic question" New topic
Author

Generic question

Jan Nowak
Greenhorn

Joined: Aug 12, 2007
Posts: 16
I am confused about this code:


Here I understand that compiler adds cast to String and therefore we have exception. But consider this:


Here I thought that there will be exception as well because of cast added by the compiler but it is ok. Can anyone please explain me this?
[ November 13, 2007: Message edited by: Jan Nowak ]
Ed Thompson
Ranch Hand

Joined: Jan 20, 2006
Posts: 43
It doesn't look to me like it's behaving properly.

I suspect it might be testing "Hello" to determine if it's an instanceof String on behalf of println, and finding it such goes no further.

When it tests 100 and finds it's not an instance of String (for println), it next test to see if its an instance of the correct class based on the generic, and fails that test, throwing the exception.

Just conjecture though. I do not think it is behaving correctly.

Interestingly, both of these work:

[ November 12, 2007: Message edited by: Ed Thompson ]

Even if the voices <i>aren't</i> real, they still have some good ideas!
Ed Thompson
Ranch Hand

Joined: Jan 20, 2006
Posts: 43
If you look at the disassembled code (m1 is your second example, m2 your first):



There is a checkcast on the String generic (m2:36), but not on the Integer generic (between M1:24 and m1:29).
[ November 12, 2007: Message edited by: Ed Thompson ]
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
There's nothing wrong with the behavior. Here's what happens: there are two overloaded versions of PrintWriter.println() that take object parameters: println(Object) and println(String). In your first program, the compiler binds your println call to println(String), which will produce a runtime exception since the actual object being passed isn't a String. In the second program, the compiler binds your println call to println(Object), which will work fine (albeit less efficiently) since String is also an Object.


SCJP 5.0
Fu Dong Jia
Ranch Hand

Joined: May 23, 2007
Posts: 131
hi!

so,the problem at "System.out.println(l.get(0));"
then invoke the code"l.get(0)",the compiler think it is a String,because of the code:List<String> l = new ArrayList<String>();so the println method will print it directly.but l.get(0) return a object,so gives exception.

but for the code:

compiler think "l.get(0)" return a Integer object,so the compiler will invoke the method: "(l.get(0)).toString" for method println.
in fact,the code:"l.get(0)" return a String object,but at runtime ,the code:

is ok!


who dare win!<br />SCJP5(94%)|SCWCD5(86%)|SCBCD(100%)|SCEA in progress
P Ventura
Ranch Hand

Joined: Jan 24, 2007
Posts: 42
Originally posted by Jan Nowak:
I am confused about this code:



Here I thought that there will be exception as well because of cast added by the compiler but it is ok. Can anyone please explain me this?


Hey that code doesn't compile: you can't add an Integer to a String List.


Objective: SCJP 1.5<br /><a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html" target="_blank" rel="nofollow">API</a><br /> <blockquote><font size="1" face="Verdana, Arial">code:</font><hr><pre><font size="2"><br />Double n1 = Double.NaN; Double n2 = Double.NaN;<br /> n1.equals(n2) // true even though Double.NaN != Double.NaN<br />-0.0 == +0.0; // true<br />Double n1 = -0.0;Double n2 = +0.0;<br />n1.equals(n2) // false even though -0.0 == +0.0<br /></font></pre><hr></blockquote>
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
Originally posted by P Ventura:

Hey that code doesn't compile: you can't add an Integer to a String List.

It's true that the code won't compile, and it's also true that the compiler won't let you add an Integer to a List<String>. But in this case it's not the latter that causes the former. ll is not a List<String> reference variable, so there's nothing wrong (at compile-time) with calling its add method with an Integer object. The compiler should issue a type safety warning, but the statement is perfectly legal.

However, the code indeed does not compile... because it's missing a semicolon on the second line.
Jan Nowak
Greenhorn

Joined: Aug 12, 2007
Posts: 16
Thank you for your answers. I was confused because I thought that with calls like l.get(0) the compiler ALWAYS adds a cast. It means that compiler adds it when necessary.

But still I am not clear about why in the second example the compiler binds the call to println(Object) and not to println(int) (autoboxing should work here) since it can distinguish String and bind the first call to println(String).




However, the code indeed does not compile... because it's missing a semicolon on the second line.


Sorry, I didn't notice that. Now it is correct.
[ November 13, 2007: Message edited by: Jan Nowak ]
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
Originally posted by Jia Fudong:
[CODE] compiler think "l.get(0)" return a Integer object,so the compiler will invoke the method: "(l.get(0)).toString" for method println.


Slight nitpick: println() won't be called with (l.get(0)).toString(), but simply with l.get(0) itself. One of the overloaded versions of println() accepts any Object parameter, so that's what gets called when it's given an Integer reference. It's the overloaded println() method that subsequently invokes the object's toString() method.
 
GeeCON Prague 2014
 
subject: Generic question