• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

generics code mixed with legacy collection

 
Pawanpreet Singh
Ranch Hand
Posts: 264
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
why the for loop creates ClassCastExcption for string object as Object can accept any type of
object (Intereg/String)


import java.util.*;

class Getter
{
public List getList()
{
List list = new ArrayList();
list.add(new Integer("3"));
list.add("str");
return list;
}
}
public class GetReturn {

public static void main(String... args)
{
List<Integer> list = new ArrayList<Integer>();
Getter get = new Getter();
list = get.getList();


for(Object i : list)
System.out.println(i);


}
}
 
Surendra Kumar
Ranch Hand
Posts: 236
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried this code, and it compiles and runs successfully pritning 3 and "str".
 
Eleanor Leong
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
When I changed
List<Integer> list = new ArrayList<Integer>();
to
List list = new ArrayList();

It runs without ClassCastException and prints 3, str.

I am confused also. Looks like the generic declaration List<Integer> causes the exception. But in fact the information of generic type should be erased after compilation.

Why the exception error!!!
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Above code will give ClassCastException at runtime because the list in for loop returns Integer object and it also has String object in it.

Can't cast String to Integer.

Whole problem is because of the assignment list = get.getList(). get.getList() returns a raw list [IntegerObject, "str"]. You are assigning this raw list into a generic List<Integer>.

Naseem
 
Surendra Kumar
Ranch Hand
Posts: 236
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Naseem,

As I said, I tried this code, and it comiles and runs fine with output 3 and "str".

Only when I change the FOR loop to below one do I get what you're talking about (ClassCastException)

for(Integer i : list)
System.out.println(i);

I wonder how you guys are getting exception, if you use Object in the FOR loop.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Surendra,

Can you post the code which you executed?
 
Surendra Kumar
Ranch Hand
Posts: 236
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
import java.util.*;

class Getter
{
public List getList()
{
List list = new ArrayList();
list.add(new Integer(3));
list.add("str");
return list;
}
}

public class GetReturn {

public static void main(String... args)
{
List<Integer> list = new ArrayList<Integer>();
Getter get = new Getter();
list = get.getList();

for(Object i : list)
System.out.println(i);
}
}
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know why you are not getting.

Here is the output of your code:

3
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at GetReturn.main(Vct.java:22)


Naseem
 
Pawanpreet Singh
Ranch Hand
Posts: 264
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have gone through the K&B book and found somthing.

May be it is right of not, but i want to share it with you

As we know the generics are just compile time validations on the code, so that we do not get run time errors
like ClassCastException. Compiler removes the generic related code (parameter type from collection) and
finally code is as pre generic collection code. But in addition to this, compiler also insert somthing in
the code as i have inserted manually.

The inital program with generic when compiler will become like this as given below.


import java.util.*;

class Getter
{
public List getList()
{
List list = new ArrayList();
list.add(new Integer("3"));
list.add("i am String");
return list;
}
}
public class GetReturn {

public static void main(String... args)
{
List list = new ArrayList();// Here generic list is converted into pre generic list
Getter get = new Getter();

list = get.getList();//a pre generic list is received by a pre generic list


for(Object i : list)
{
Integer intObj = (Integer) i;/* this code is added by compiler as generic type parameter was <Inetegr>, so here ClassCastException comes. */
System.out.println(intObj);
}

}
}

Naseem, Correct me if i am wrong
 
Pawanpreet Singh
Ranch Hand
Posts: 264
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Check below code from K&B(page 577), here i just added for loop, that is creating ClassCastException. Here we are adding
one string data into integer list

import java.util.*;
class Adder
{

public void iter(List list)
{
list.add(new Integer(4));

list.add("wrong data");
}
}
public class TestBadLegacy1 {

public static void main(String... args)
{
List<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(new Integer(2));
list.add(new Integer(3));
Adder add = new Adder();
add.iter(list);



for(Object i:list)
{
System.out.println("integer :"+i);
}
}
}
 
Pawanpreet Singh
Ranch Hand
Posts: 264
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can anybody SCJP 5.0 guy can correct me if my last two replies on Generics are incorrect.
 
Eleanor Leong
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Pawan.
Its a very good answer.
I understand now.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Pawan preet:
Can anybody SCJP 5.0 guy can correct me if my last two replies on Generics are incorrect.



They are correct. When there is cast, exception will be thrown. Question is when compiler cast.

Here I am taking three different cases for object retrieval from the list and along with I am also showing you the output from javap -c GetReturn

Case 1:



Case 2:



Case 3:



In all the above cases, object returned from the list is assigned to Object not Integer but there is a cast operation only in the third case done by compiler. (i.e., in-enhanced for-loop)

So now its clear that only enhanced for loop will return ClassCastException because of implicit cast in that case even if you assign it in Object.


Naseem
[ August 08, 2006: Message edited by: Naseem Khan ]
 
Pawanpreet Singh
Ranch Hand
Posts: 264
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Naseem
 
Ivan Rebrov
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following code compiles and runs by me without erors and exceptions.
Why don't I receive the same result as others do?

Guys, are you sure, that this code isn't legal?
K&B says that this code is Ok... (page 577)





[ August 09, 2006: Message edited by: Ivan Rebrov ]
[ August 09, 2006: Message edited by: Ivan Rebrov ]
 
Ivan Rebrov
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
any ideas?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic