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.