GeeCON Prague 2014*
The moose likes Beginning Java and the fly likes Generics Doubt (Casting) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Generics Doubt (Casting)" Watch "Generics Doubt (Casting)" New topic
Author

Generics Doubt (Casting)

Suresh Rajadurai
Ranch Hand

Joined: Feb 22, 2007
Posts: 58
Hi folks,

Please have a look at the following code:




Please see the line which I marked (A).
If I replace this line with "for (Object obj : c)" its giving run-time exception.

Could anybody please throw some light on it please.


much appreciated, many thanks,

Regards

Suresh.
Daesung Park
Ranch Hand

Joined: Mar 22, 2007
Posts: 68
I couldn't find any problem in your code and execution after replacing the line.

What is the runtime exection message?

Daesung Park

BLOG
Suresh Rajadurai
Ranch Hand

Joined: Feb 22, 2007
Posts: 58
Exception in Thread "main" java.lang.ClassCastException: Car cannot be cast to Bus at test.main(gen13a.java:19).

The line number 19 is where the statement "for (Object obj : b)"


Please note that, in the forum, I did not type the import statement even though I had it in my program. Therefore if you add 2 to the lines of code above, the 19th line is the "for loop" line.


Suresh
amitabh mehra
Ranch Hand

Joined: Dec 05, 2006
Posts: 98
I think this is because of way the enhanced loop works behind the scene.
The class should implement the interface Iterable<T>

The enhanced for loop, at compile time, is converted something similar to:


So now when you use 'b' (arraylist without generics) in your for loop, it works fine.
But when you put in a generic (car or bus), Iterator of that is fetched and for the odd entry it gives a run time exception.

By the way, try not to mix the generic and non-generic collection. The compiler wont complain by giving compile time errors but still point this to you by giving warning.

Harshit Rastogi
Ranch Hand

Joined: Apr 15, 2008
Posts: 131
Hi
If you try following code:


List<Object> list = new ArrayList<Object>();
list.add(new Bus());


The second line will give compile time error even though Bus is an Object. Similar thing is happening in your code. You are trying to retreive Object from list c which has Bus objects.


<a href="http://technologiquepanorama.wordpress.com" target="_blank" rel="nofollow">My Techie Blog</a><br /><a href="http://www.java-questions.com" target="_blank" rel="nofollow">Java Questions</a>
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 605

Harshit Rastogi wrote:Hi
If you try following code:



The second line will give compile time error even though Bus is an Object. Similar thing is happening in your code. You are trying to retreive Object from list c which has Bus objects.


I don't see why adding a Bus object to an Generic Object ArrayList should give a compilation error?
After all Bus is of type Object ... So adding a Bus should work fine.

What will not work is,



As for the original questions - the code works fine for me and it should!
What should not work is,

which would compile fine but throw a run time exception.


Cheers - Sam.
Twisters - The new age Java Quiz || My Blog
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19697
    
  20

When I decompile test.class this is the contents of the main method (I've added the comments):

As you see, even though you don't use the declared generic type Bus, the compiler does.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 605

Rob Prime wrote:When I decompile test.class this is the contents of the main method (I've added the comments):

As you see, even though you don't use the declared generic type Bus, the compiler does.


Can you post the source code for this? It cannot be the original source code? The for loop of the original source code is

which should decompile to


The Object type Bus or Object is not related to what you used in the Generic declaration but to what you used in the enhanced for loop.

Hence if you use for (Object obj : b) as originally posted the code should compile and execute without and issues.
If you use for (Bus obj : c) then it would give you a class cast exception. This has nothing to do with generics as the de-compiled code illustrates.

The only incorrect use of Generics in the entire program is
ArrayList<Bus> c = (ArrayList<Bus>)b;
which allows the program to compile but is sure to cause run time exceptions when used in statements like for (Bus obj : c).
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19697
    
  20

Sam Mercs wrote:Can you post the source code for this? It cannot be the original source code? The for loop of the original source code is

which should decompile to

Right. I should have mentioned that code was decompiled with the for-loop over c, not b. It therefore uses c's generic type. With b everything works fine because it doesn't cast the contents.
amitabh mehra
Ranch Hand

Joined: Dec 05, 2006
Posts: 98
Rob Prime wrote:
Right. I should have mentioned that code was decompiled with the for-loop over c, not b. It therefore uses c's generic type. With b everything works fine because it doesn't cast the contents.


Which means that I was kind of right with my understanding
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 605

Rob Prime wrote:
Right. I should have mentioned that code was decompiled with the for-loop over c, not b. It therefore uses c's generic type. With b everything works fine because it doesn't cast the contents.


And now for some scary part
When I compile and Run the code (shown below) using my eclipse IDE, the code runs fine.


and the class file de-compiles to


Running the code gives me this output on the eclipse console,
Car@130c19b
Bus@1f6a7b9
[Car@130c19b, Bus@1f6a7b9]

However when I compile the same using my command prompt,

The class file I get de-compiles to


Running the code from command prompt throws the class cast exception
Exception in thread "main" java.lang.ClassCastException: Car
at test.main(test.java:18)


Any Explanation why this should happen? This is beyond my understanding ... atleast for now
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19697
    
  20

Probably a difference in compilers.
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 605

Rob Prime wrote:Probably a difference in compilers.


I don't see how ... I just got standard Java 1.5 compiler installed ...

Oh well!!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19697
    
  20

But does Eclipse use that one? I can clearly see an exe called "eclipsec.exe" in my Eclipse installation folder. That looks to be Eclipse's own internal compiler.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Rob Prime wrote:But does Eclipse use that one? I can clearly see an exe called "eclipsec.exe" in my Eclipse installation folder. That looks to be Eclipse's own internal compiler.


eclipsec.exe is a console-linked executable for Eclipse. See this link for some info.

But Eclipse does use its own compiler - the JDT Core compiler, which is defined as "org.eclipse.jdt.internal.compiler.batch.Main" packaged in plugins/org.eclipse.jdt.core_3.2.0.jar. I think you can also download it separately (and as a side note, I think the newer versions of Tomcat use the JDT to compile JSPs by default).


Steve
 
GeeCON Prague 2014
 
subject: Generics Doubt (Casting)