Bohdan Petrenko
Bohdan Petrenko

Reputation: 1155

ClassCastException when cast generic list to specific type

In the following code I got ClassCastException only on the 6th line when get actual value from List of strings as integer. But I want to get this exception earlier in 4th line. As you can see 5th line works correct without ClassCastException

public static void main(String[] args) {
    List<String> original = Arrays.asList("1", "2", "3");
    Object obj = original;
    List<Integer> li = (List<Integer>)obj;
    System.out.println(li); //[1, 2, 3]
    Integer ei = li.get(0); //java.lang.ClassCastException
}

I understand that List contains only references to actual objects (values) and don't know anything about actual content before read. Is there any correct way to throw ClassCastException on the 4th line?

Upvotes: 1

Views: 973

Answers (4)

eham
eham

Reputation: 1

cast object to array of integer needs to be convert first string then Integer.

        List<String> original = Arrays.asList("1", "2", "3");
        Object obj = original;
        List<Integer> li = (List<Integer>)obj;
        System.out.println(li); //[1, 2, 3] 
        Integer ei = new Integer(String.valueOf(li.get(0))); //java.lang.ClassCastException

Please see also how-to-cast-an-object-to-an-int

Upvotes: 0

Karol Dowbecki
Karol Dowbecki

Reputation: 44942

You have bypassed the compiler check for generic types by using Object and casts:

List<Integer> li = (List<Integer>) (Object) Arrays.asList("1", "2", "3");
Integer i = li.get(0);

You won't get a ClassCastException in line 4 since in runtime generic information is not present due to Type Erasure. The code is compiled more or less as:

List li = (List) Arrays.asList("1", "2", "3"); // all good, still List
Integer i = (Integer) li.get(0); // ClassCastException

Upvotes: 1

LppEdd
LppEdd

Reputation: 21114

The only compile-time warning you can get is

java: unchecked cast
  required: java.util.List<java.lang.Integer>
  found:    java.lang.Object

Which can be obtained using the

-Xlint:unchecked

compilation parameter.
At runtime, it's not possible, as upcasting is always allowed to Object, and downcasting is always allowed from Object in this case (as you're targeting a List).

Upvotes: 1

rzwitserloot
rzwitserloot

Reputation: 102830

As the compiler warning was trying to tell you (the warning on line 4): The generics bits in a type assertion (a cast where the thingie in the parentheses is a non-primitive type) are not checked at all, the compiler just trusts you.

it's literally a type assertion (you, the programmer, is informing the compiler that it should make a presumption about what's in there).

The only way to do something like this is to loop through each and every element in that list and check if it is an Integer.

Upvotes: 1

Related Questions