Below is the first Java generics I've ever written :
public class MyClass {
public static <T> T castToAnotherType(Object param) {
T ret = null;
try {
ret = (T) param;
} catch (ClassCastException e) {
System.out.print("Exception inside castToAnotherType()");
}
return ret;
}
public static void main(String[] args) {
try {
String obj = MyClass.castToAnotherType(new Object());
} catch (ClassCastException e) {
System.out.print("Exception outside castToAnotherType()");
}
}
}
The result is "Exception outside castToAnotherType()". Why did the exception not occur inside the generic method?
T
is effectively erased during compilation. See here:
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
- Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
- Insert type casts if necessary to preserve type safety. Generate bridge methods to preserve polymorphism in extended generic types.
- Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
So your castToAnotherType
gets T
erased into ca. the following:
public static Object castToAnotherType(Object param) {
Object ret = null;
try {
ret = (Object) param;
} catch (ClassCastException e) {
System.out.print("Exception inside castToAnotherType()");
}
return ret;
}
Which does obviously not produce any ClassCastException
.
main(...)
is a different story, it results into the following:
public static void main(String[] args) {
try {
String obj = (String) MyClass.castToAnotherType(new Object());
} catch (ClassCastException e) {
System.out.print("Exception outside castToAnotherType()");
}
}
Which produces the ClassCastException
when trying to cast Object
to String
.
Please see the Type Erasure part of the Generics tutorial.
Well, since the compiler erases the generic type parameters, the casting inside the method is essentially equivalent to :
Object ret = null;
try {
ret = (Object) param;
}
...
which is not a problem, regardless of what you pass to your method (since any Object can be cast to Object).
However, when you try to assign that Object to a String, in your main method, the ClassCastException
occurs, since Object
cannot be cast to a String
.
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