Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type safety with generics in Java

Tags:

java

generics

I've encountered a behaviour of generics in Java that I completely can't understand (with my .NET background).

public class TestGeneric<T>
{
    public void get (Object arg)
    {
        T temp = (T) arg;

        System.out.println(temp.toString());

        return;
    }
}

TestGeneric<Integer> tg = new TestGeneric<Integer>();
tg.get("Crack!!!");

Please tell me why I'm not getting ClassCastException in get, moreover, in Idea I see temp as String after assignment and having value of "Crack!!!". Also, how could I have that ClassCastException throwed? I'm using JDK 1.7.0_07 on Windows 7 x64.

like image 938
starteleport Avatar asked May 22 '13 10:05

starteleport


2 Answers

The reason you are not getting a class cast exception is that Java generics are implemented through type erasure. Unlike .NET generics that required significant changes to CLS, Java generics are processed entirely in compile-time. At runtime, the cast to T is ignored. In order to check type at runtime, you need to store Class<T>, and use its methods to check the type of a parameter passed in:

public class TestGeneric<T>
{
    private Class<T> genClass;
    public TestGeneric(Class<T> t) {genClass = t;}
    public void get (Object arg)
    {
        if (!genClass.isInstance(arg)) {
            throw new ClassCastException();
        }
        T temp = (T) arg;

        System.out.println(temp.toString());

        return;
    }
}

TestGeneric<Integer> tg = new TestGeneric<Integer>(Integer.class);
tg.get("Bang!!!"); // Now that's a real Bang!!!
like image 168
Sergey Kalinichenko Avatar answered Oct 28 '22 16:10

Sergey Kalinichenko


This is because the generic type T has no defined bounds so it is treated as an Object. Casting something to T will not cause a ClassCastException in this case.

However, if your class definition was public class TestGeneric<T extends Number>, then you would get the ClassCastException if you passed in a String into get().

like image 44
nitegazer2003 Avatar answered Oct 28 '22 16:10

nitegazer2003