• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Generics - need help

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi ranchers

I was trying to see how generics works ..

I have few doubts with regards to the code given below...please help me clear them..



Output:

Me
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
myself
and


1)When a copy of 'li' is passed to the parameter 'list' in addstuff() ,wont 'list' also become type-safe.?
Apparently, it isnt - so what is the reason -type erasure?? ...please could you explain ...

2)What is actually happening in the 'foreach'...?
where is the casting from Integer to String taking place....wont the elements in 'li' be assigned to Object o ,iteratively?


Thanks,
Vinitha
 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As per my knowledge I am trying to explain your doubt
Type erasure is only for compile time checking. It doesn't exist at runtime. In your code if you change the signature
public void addstuff(List<String> list) then list.add(43); will cause a compile time error. at that time you are not able to add integer in the list whose type is String.

When you are passing a generic list to a non generic method all the security will vanish there. You can add anything in that list.


I copy pasted your code and it executing fine. Not throwing any exception whatever you mentioned. So please execute your code once again.

 
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The magic is in "reference" type and the "object" its pointing.

Vinitha Palani wrote:
1)When a copy of 'li' is passed to the parameter 'list' in addstuff() ,wont 'list' also become type-safe.?
Apparently, it isnt - so what is the reason -type erasure?? ...please could you explain ...
2)What is actually happening in the 'foreach'...?
where is the casting from Integer to String taking place....wont the elements in 'li' be assigned to Object o ,iteratively?


(1)At compile time, In method 'addstuff()', the parameter define is simple 'List list', which is capable of accepting any object. That's why one can add '43' in it, (2) but while executing the code (during run time) in the for each loop, JVM finds object as a primitive int, where as its expect its as a String, that's why it throws an exception.

HTH
 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Dwijen

Thanks!

"When you are passing a generic list to a non generic method all the security will vanish there. You can add anything in that list." - OK ....this answers the first question..

but i am still geting the exception ...did you change anything?

 
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vinitha Palani wrote:
but i am still geting the exception ...did you change anything?



The question is, did you use any IDE or something for this code?? There was a long discussion on this about when the compiler inserts a type cast for a generic element. I'll try to search it and provide it...
 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found the thread. Here you can find a good discussion of the problem that you are facing...
 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sagar,

Thanks for the reply.
But the "int" will get Autoboxed wont it?
I tried changing it to Integer -




But the output is still -

In the listMe
In the listmyself
In the listand
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at myfirstapplication.MyClass.main(MyClass.java:14)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 se


Cheers
Vinitha
 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes,i used NetBeans IDE 6.5.1..

Ankit,
Thanks for the link..i will go through it....
 
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

The response about the runtime type safety is correct according to K&B book.
It's behaviour is like that to enable working together with old legacy code.

About the exception, it does happen, i was surprised too.
I thought Object o in the enhanced for loop will be able to handle it. Well if it's String s that's in the loop, that's another story, hee hee

Anyway, i assume the exception occurs because the reference li is checked for type safety because it's declared with generics type safety. I thought it is only helping in validate what we add into .. not what we get from ..

And thanks for bringing this topic up, as i'm just into the generics chapter here !

(Going for the discussion thread recommended by previous post ..)

Regards,
Albert Kam
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dwijen Bhattacharjee wrote:
When you are passing a generic list to a non generic method all the security will vanish there. You can add anything in that list.


This is the one of the drawbacks of new feature, Generics in Java 5, suppose you have an API which is built as per Java 1.4 spec, and it contains the methods, same as the original example,


Dangerous.
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vinitha Palani wrote:
But the "int" will get Autoboxed wont it?


Yes, it gets "autoboxed" to new Integer(43).
But the thing is, when you say, 'List list', its something like defining, 'List <Object> list', and you know every class in Java is derived from 'Object', so no matter whether you insert int, Integer, Double, OR MyDumbClass's object, its gonna complains at run time, when he dosen't found what he expected (Strings)


 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sagar Rohankar wrote: when you say, 'List list', its something like defining, 'List <Object> list',



Well this is a minute detail but this is not true. You can do this



but you can't do this



I know this is about assignment to the list and what you said applies to adding elements to the list, but I couldn't stop myself from pointing this out as I don't want anyone to have confusions or misconceptions. Actually List list is equivalent to List<? extends Object>...
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:

Sagar Rohankar wrote: when you say, 'List list', its something like defining, 'List <Object> list',



Well this is a minute detail but this is not true. You can do this



but you can't do this



Agreed, but I'm talking in context with the actual code, which takes List as a parameter.

Ankit Garg wrote:
.. but I couldn't stop myself from pointing this out as I don't want anyone to have confusions or misconceptions. Actually List list is equivalent to List<? extends Object>...


Yeah, thanks for the more technical explanation, its "bounded wildcard parametrized types"(If I remeber correctly ). But a little doubt, what is the difference between List<Object> and List<? extends Object>
 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sagar Rohankar wrote:what is the difference between List<Object> and List<? extends Object>



The difference is obvious.

 
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
* Both object reference variable are refer to only one object :

The type safe reference variable in main method is temporary hold(or use any other word)
when you call add stuff() method,

but variable "list" is not type safe.

* if you modify code exception will not come.


 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Chaitanya did you try your code?? The exception doesn't come when you add the element. The exception comes while iterating the List...
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Ankit

Not allowed you to add objects.
whereas, this declaration works smoothly,

The question is, why such behavior ?
 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well I think here you'll get a compile time warning



Now after this warning, if any exception comes in your code, then you are responsible for it. So if you write



then you can't blame the compiler that it didn't complain that something like this could happen.

But when you write



Here you won't get any warnings. So it is the responsibility of the compiler to make sure, that no ClassCastException occurs at runtime. That's why it disallows you to add elements to it. Taking this same example, here, The actual type of the ArrayList is String, but we are using it with a reference of type ? extends Object, so that means that we can try to add Integer to it as Integer is a subtype of Object. But with the ?, it means that the actual type is not known, so it is not sure that it is Integer or String. That's why it disallows you to add anything to the list...
 
Chaitanya Jadhav
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:Chaitanya did you try your code?? The exception doesn't come when you add the element. The exception comes while iterating the List...



Hi Ankit
See the full modified code.
If you modified the code it will run fine. but i don't known whats gotcha.



 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is the gotcha my boy



Just go through the thread that I gave the link to for clarification...
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:

Here you won't get any warnings. So it is the responsibility of the compiler to make sure, that no ClassCastException occurs at runtime. That's why it disallows you to add elements to it.


So whats the use of such declaration, Whats the use any facility which we can't use. Just to avoid compile time warnings ?, which, an average programmer with knowledge of Java generics, can possibly avoid them.

Ankit Garg wrote:
Taking this same example, here, The actual type of the ArrayList is String, but we are using it with a reference of type ? extends Object,


If that's so, then why this code works, the List#add() methods works here.

 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sagar Rohankar wrote:

Ankit Garg wrote:
Taking this same example, here, The actual type of the ArrayList is String, but we are using it with a reference of type ? extends Object,


If that's so, then why this code works, the List#add() methods works here.



Yes its my fault. List is not equivalent to List<? extends Object>. Actually there is no direct way of representing an untyped List using generics.

Sagar Rohankar wrote:

Ankit Garg wrote:

Here you won't get any warnings. So it is the responsibility of the compiler to make sure, that no ClassCastException occurs at runtime. That's why it disallows you to add elements to it.


So whats the use of such declaration, Whats the use any facility which we can't use. Just to avoid compile time warnings ?, which, an average programmer with knowledge of Java generics, can possibly avoid them.



Well the use is to retrieve elements. Suppose you want to create a method that will accept a List of Serializables and serialize the objects, then you can do this

 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:Actually there is no direct way of representing an untyped List using generics.



Ankit Garg wrote:
Well the use is to retrieve elements. Suppose you want to create a method that will accept a List of Serializables and serialize the objects, then you can do this


And you get it right, Thanks buddy to making it clear for me I need to dive deep into Generics
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:I found the thread. Here you can find a good discussion of the problem that you are facing...


Ankit, do you know why there is an exception in this specific case? It looks as if it might be a detail related to the for-each loop implementation. Simply assigning to an Object variable doesn't do the trick.

 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Everyone

I ran few test programs to get clarity on this one..i am sharing them ,and summarizing my understanding and what people found out so far,for the purpose of learners like me.

Please correct me if i am wrong -

1.




Output :

run:
Me
myself
and
43
BUILD SUCCESSFUL (total time: 1


2.



Output :
run:
43
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at myfirstapplication.MyClass.main(MyClass.java:14)
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seco


3.To further substantiate this -



Compiler throws an error saying "Incompatible types found:java.lang.Integer required:java.lang.String".

4.


Output:
run:
Me
myself
and
43
BUILD SUCCESSFUL (total time: 2 seconds)

5.

Output :
run:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Me
at myfirstapplication.MyClass.main(MyClass.java:16)
myself
and
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)



To summarize -
The foreach loop is designed with "generics" and type safety in mind.
When we declare
List<String> li =new ArrayList<String>();
'li' is supposed to hold ONLY string .
But when we give a copy of 'li' to 'list' which is not type-safe,the whole 'generics-assures-type-safety' thing
goes awry.
But ,when we iterate the list ,which is supposed to contain elements of type String ONLY ,using a 'for..each' ,
it expects to find elements which of type String ONLY.


Cheers,
Vinitha





 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hey everyone

I am rephrasing the last line in the previous post -

But ,when we iterate the list ,which is supposed to contain elements of type String ONLY ,using a 'for..each' ,
The 'for...each' expects to find elements of type String ONLY.


thanks,
Vinitha

 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
an interesting finding and ofcourse , few questions

This doesnt give compliler error
List list =new ArrayList<String>();
list.add("Me");
list.add("myself");
list.add("and");
list.add(new Integer(43));


But this does

List<String> list =new ArrayList();
list.add("Me");
list.add("myself");
list.add("and");
list.add(new Integer(43));



So does this means that type safety is decided by the reference variable ..
then why do we declare like this
List<String> list =new ArrayList<String>();

wouldnt this be enuf ??
List<String> list =new ArrayList();

Cheers
Vinitha



 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

I would like to add my penny to the discussion. This is my first post so be gentle.

is simply syntacticly equal to


Because 'li' is of List<String> reference type when passed to the addStuff method it is erased of its own type safety so we can add then anything to it. We also need to note that we pass by value, so when the method addStuff finishes, 'li' contains all the four elements and in main method still refers to the same List<String> type which is passed to the expression part of the foreach statement. 'li' returns Iterator<String> in our foreach loop and casts every element to String as shown above. Of course the cast of Integer type will throw runtime exception.
 
Vinitha Palani
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Peter,
You hit the nail on the head..!
Thanks.

Any answers for the questions in my last post..?
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am kalpita lawande.I am planning to give scjp 1.5 in june 2009.
can you please tell me which chapters are important and how many mock exams should i give?
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vinitha Palani wrote:
Any answers for the questions in my last post..?


Just look out the discussion between me and Ankit regrading this. Still, here are my short notes on this,
List list =new ArrayList<String>();
consider this statement as,
List<Object> list =new ArrayList<String>();
and you know this is NOT valid, Now one important point to remember, this is for sake of understand, I didn't found any doc/guide which adhere or support this my assumption.

Now, second thing, is little tricky,
List<String> list =new ArrayList();
compiler saw it as,
List<String> list =new ArrayList<Object>();//unchecked warnings.
It throws error, when other than string object is added into it.
because, the method calls are depends upon the reference type, and when compiler saw the reference is of typeList<String>, it invokes the method from List interface as, List#add(String s);, and you see, '43' in not a string.

Vinitha Palani wrote:
So does this means that type safety is decided by the reference variable ..


You can say that, but have you noticed one thing, when you do that, compiler issues warning, but in this case it won't
List<String> list =new ArrayList<String>();

And to explain this point from the master in Generics, check out this link, it clears all the doubts about this point and all the other related to generics.

HTH

 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

kalpita lawande wrote:I am kalpita lawande.I am planning to give scjp 1.5 in june 2009.
can you please tell me which chapters are important and how many mock exams should i give?


Its better to create a new thread for your doubts, rather hijacking others thread, anyways, scroll through this SCJP FAQ, it answers most of your doubt.

And welcome to JR and Best Luck
 
Dwijen Bhattacharjee
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now I have a doubt --
whatever the code Vinitha posted at the beginning I simply copy pasted the same code in eclipse and it's generating the output-
Me
myself
and
43

the same code If i compile and run from command line its generating the output--
Me
myself
and
Exception in thread main java.lang.ClassCastException:java.lang.Integer

Both using jdk1.5.0_09.If The problem is with the for..each loop . Then why its generating two different output?
First I thought may be problem with my configuration . But then i thought if both the version is 1.5 then it should present the same output in all the places. Please clarify the doubt.
 
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sagar Rohankar wrote:
List list =new ArrayList<String>();
From Java 5, consider this statement as,
List<Object> list =new ArrayList<String>();
and you know this is valid, Now one important point to remember, this is for sake of understand, I didn't found any doc/guide which adhere or support this my assumption.



Again this might be miss-leading someone as List<Object> list =new ArrayList<String>() is not allowed since that will not compile. List<Object> means list of Object's (not any object which is an Object).
 
Sagar Rohankar
Ranch Hand
Posts: 2908
1
Spring Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vijitha Kumara wrote:Again this might be miss-leading someone as List<Object> list =new ArrayList<String>() is not allowed since that will not compile.


Oops, I modified my previous post, But whenever I found this, List list; I conclude it as List<Object> list;. Is it OK ?
 
Vijitha Kumara
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you say List list it's raw type, it's allowed in order to support legacy code (since in JDK5 List is parameterized). As I said before List<Object> means list of type Object's.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dwijen Bhattacharjee wrote:Now I have a doubt --
whatever the code Vinitha posted at the beginning I simply copy pasted the same code in eclipse and it's generating the output-
Me
myself
and
43

the same code If i compile and run from command line its generating the output--
Me
myself
and
Exception in thread main java.lang.ClassCastException:java.lang.Integer

Both using jdk1.5.0_09.If The problem is with the for..each loop . Then why its generating two different output?
First I thought may be problem with my configuration . But then i thought if both the version is 1.5 then it should present the same output in all the places. Please clarify the doubt.


I've said this many times. Do not use Eclipse, its compiler doesn't always produce the same results as javac.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Peter Murach wrote:Hi all,

I would like to add my penny to the discussion. This is my first post so be gentle.

is simply syntacticly equal to


Because 'li' is of List<String> reference type when passed to the addStuff method it is erased of its own type safety so we can add then anything to it. We also need to note that we pass by value, so when the method addStuff finishes, 'li' contains all the four elements and in main method still refers to the same List<String> type which is passed to the expression part of the foreach statement. 'li' returns Iterator<String> in our foreach loop and casts every element to String as shown above. Of course the cast of Integer type will throw runtime exception.


That's a very good point, Peter. I hadn't thought about that (we are calling iterator() on a generic collection.)

Thanks,

Ruben
reply
    Bookmark Topic Watch Topic
  • New Topic