This question was inducted by this StackOverflow question about unsafe casts: Java Casting method without knowing what to cast to. While answering the question I encount
Version 1 is preferable because it fails at compiletime.
Typesafe version 1 non-legacy code:
class Erasure {
public static T unsafeIdentity(T x) {
//no cast necessary, type checked in the parameters at compile time
return x;
}
public static void main(String args[]) {
// This will fail at compile time and you should use Integer c = ... in real code
Object c = Erasure.unsafeIdentity("foo");
System.out.println(c.getClass().getName());
}
}
Typesafe version 2 legacy code (A run-time type error [...] In an automatically generated cast introduced to ensure the validity of an operation on a non-reifiable type and reference type casting):
class Erasure {
public static T unsafeIdentity(Object x) {
return (T) x;
//Compiled version: return (Object) x;
//optimised version: return x;
}
public static void main(String args[]) {
// This will fail on return, as the returned Object is type Object and Subtype Integer is expected, this results in an automatic cast and a ClassCastException:
Integer c = Erasure.unsafeIdentity("foo");
//Compiled version: Integer c = (Integer)Erasure.unsafeIdentity("foo");
System.out.println(c.getClass().getName());
}
}
TypeSafe version 3 legacy code, Methods where you know a supertype everytime (JLS The erasure of a type variable (§4.4) is the erasure of its leftmost bound.):
class Erasure {
public static T unsafeIdentity(Object x) {
// This will fail due to Type erasure and incompatible types:
return (T) x;
// Compiled version: return (Integer) x;
}
public static void main(String args[]) {
//You should use Integer c = ...
Object c = Erasure.unsafeIdentity("foo");
System.out.println(c.getClass().getName());
}
}
Object was only used to illustrate that Object is a valid assignment target in version 1 and 3, but you should use the real type or the generic type if possible.
If you use another version of java you should look at the particular pages of the specification, I don't expect any changes.