我希望这段代码抛出ClassCastException:
public class Generics {
public static void main(String[] args) {
method(Integer.class);
}
public static <T> T method(Class<T> t) {
return (T) new String();
}
}
但事实并非如此。将String转换为T不会失败,直到我以某种方式使用返回的对象,如:
public class Generics {
public static void main(String[] args) {
method(Integer.class).intValue();
}
public static <T> T method(Class<T> t) {
return (T) new String();
}
}
背景:我创建了一个使用JAXB来解组XML文件的类。它看起来像这样:
public static <T> T unmarshal(File file, Class<? extends T> clazz)
根据root-Element是否为匿名类型,返回T或JAXBElement。 JAXBElement当然不能投入T. 在我的单元测试中,我只调用unmarshal()而没有对结果做任何事情,一切正常。在Code中,它失败了。
为什么不直接失败?这是一个错误吗?如果没有,我想了解原因。
答案 0 :(得分:4)
如果未明确指定T,则类型擦除会将其视为Object
。因此,你的String对象可以被铸造......
答案 1 :(得分:4)
您未明确指定,因此T为Object。
所以看起来像这样
public class Generics {
public static void main(String[] args) {
Generics.method(Integer.class).intValue();
}
public static Object method(Class<Object> t) {
return (Object) new String();
}
}
如果指定通用参数:
public class Generics {
public static void main(String[] args) {
Generics.<Integer>method(Integer.class).intValue();
}
public static <T> T method(Class<T> t) {
return (T) new String();
}
}
你会得到那个例外。
答案 2 :(得分:1)
我认为您可以像这样制定更强大的方法定义:
public static <T extends Number> T method(Class<T> t) {
return //// some code.
}
在这种情况下,行返回new String()只是无法编译。
但行返回new Integer(123);编译,工作,不需要铸造。