Rachit Kyte.One
Rachit Kyte.One

Reputation: 1986

Type casting an object to any Collection type

We recently faced a bug in our code which was basically related to OOPs concepts.

class ABC
{
    String a;
    ABC(){
        a = "abc";
    }
}

public class Main {


    static Object listABC() {
        List<ABC> listOfABC = new ArrayList<>();
        listOfABC.add(new ABC());
        return listOfABC;
    }

    public static void main(String[] args) throws java.lang.Exception {

        List<Long> listLong = (List) Main.listABC();
        System.out.println(listLong.get(0));
    }
}

Output: ABC@642c39d2

Shouldn't this raise a run time exception ? Can someone point me to the correct direction as to why doesn't this code raise an exception?

Upvotes: 5

Views: 264

Answers (2)

Jason C
Jason C

Reputation: 40335

Generic types are erased, and in your example info about them no longer exists at runtime. They're only a compile time aid. Casting List<T> to List also discards info about the type at compile time, although it's still a valid cast.

So as long as you're doing legal casts at every step, which you are, it'll compile fine. At runtime the info about the type in the list is gone here.

If you tried to cast get(0) to a Long then youd get a classcastexception, since the item itself is an ABC.

Upvotes: 7

SomeJavaGuy
SomeJavaGuy

Reputation: 7347

The answer is pretty simple. Generics are compile time components to ensure compile time compatibility. Generics are gone after compiling and hence don´t exist at Runtime anymore.

As Object listABC does return a List, (List) Test.listABC(); doesn´t throw an exception, because it´s valid as it actually returns a List.

you can assign it to List<Long> listLong because at runtime listLong doesn´t know about it´s Long generic anymore.

As a result this is, even though it looks wrong, valid executable code.

also the only reason this does work is that there is a PrintStream#println(Object) method, otherwise you´d get an Exception because your trying to call it with a wrong type as you can see in the following example.

static Object listABC() {
    List<Test> listOfABC = new ArrayList<>();
    listOfABC.add(new Test());
    return listOfABC;
}

public static void main(String[] args) throws java.lang.Exception {

    List<Long> listLong = (List) Test.listABC();
    System.out.println(listLong.get(0));
    test(listLong.get(0));
}

private static void test(Long longvalue) {
    System.out.println("TEST");
}

O/P

ABC@19e0bfd
Exception in thread "main" java.lang.ClassCastException: ABC cannot be cast to java.lang.Long
at ABC.main(ABC.java:19)

Upvotes: 3

Related Questions