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.
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!!!
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().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With