RawType and ClassCastException
import java.util.*;
class RawType
{
public static void main(String[ ] args)
{
List<Integer> l = new ArrayList<Integer>( );
insert(l);
Object o = l.get(0); <This works
System.out.println(o);
for(Object s :l ) < This doesen't work, exception thrown, why?
System.out.println(s);
}
static void insert(List l1)
{
l1.add(new Float(12.3));
}
}
I am trying to store a List<Integer> refernce in an Object using the modified for loop. When the "get( )" method is used, it correctly stores a Float in Object. However, in the modified for loop, it throws a ClassCast Exception.
Because the following code:List<Integer> l = new ArrayList<Integer>();
for (Object s : l)
System.out.println(s);
Is converted by the Java compiler using type erasure to something like this:List l = new ArrayList();
Integer s;
for (Iterator iterator = l.iterator(); iterator.hasNext(); ) {
s = (Integer)iterator.next();
System.out.println(s);
}
Since you have a Float object in your list then you have the ClassCastException.
By the way when compiling your code you got the "unchecked or unsafe operations" warnings.
Regards
Why would the Object s get replaced by Integer s? I am trying to store whatever kind of object there might be in List<Integer> into an Object.
How does Object o = l.get(0) not throw any ClassCastException.
And yes, i am aware than an unchecked exception is thrown which can be done away by using java xlint:unchecked.
Your problem is that you are not using generics correctly. You have corrupted your generic list.
List<Integer> l = new ArrayList<Integer>( );
insert(l);
static void insert(List l1)
{
l1.add(new Float(12.3));
}
Your list should either be a list of Integers and therefore you should only add integers to it or it should be a list of objects.
List<Integer> l = new ArrayList<Integer>( );
insert(l);
static void insert(List<Integer> l1)
{
l1.add(new Float(12.3)); < this will now not compile
}
List<Object> l = new ArrayList<Object>( );
insert(l);
static void insert(List<Object> l1)
{
l1.add(new Float(12.3)); < this will compile
}
The non-generic interfaces where included in the generic classes to allow for backward compatibility. However, you should avoid mixing them. Either use generics or don't. Don't use them in one place and then pass them into another where you don't refer to it as a generic.
I do know that i have corrupted my generic list, by using a non-type safe parameter in the insert( ) method, and i am doing it to test a few things.
What i need to know, is when u retrieve an object from a List<Integer> using get( ) and store it in Object, it works fine. So retrieving a Float from a List<Integer> and storing it in an Object works fine.
But, try retrieving the same Float and storing it in an Object using the modified-for loop and it throws an exception.
I need to know why is the exception thrown in second case?
Probably the foreach is converting the list of an Interable<Integer> by calling interator.
Here's the answer:
ArrayList implements the Iterable interface (via java.util.collection) in order to use the enhanced for loop. Here's the signature for the Iterable interface:
package java.lang;
public interface Iterable< E > {
/**
* Returns an iterator over the elements in this collection.
* There are no guarantees concerning the order in which the elements
* are returned (unless this collection is an instance of some class
* that provides such a guarantee).
*
* @return an iterator over the elements in this collection
*/
Iterator< E > iterator();
}
The Iterable interface returns an Iterator which in this case would be an Iterator<Integer>. The Iterator<Integer> expects to find and retrieve an Integer from the List. However, when it finds a Float, it has no hope of converting it into an Integer, and hence a ClassCastException is thrown.
Thanks for all your replies.