问题描述
我正在尝试运行以下代码,由于类型推断,这些代码在 JDK8 下编译得很好:
I'm trying to run the following code which is compiled fine under JDK8 thanks to type inference:
public static <A,B> B convert(A a) {
return (B) new CB();
}
public static void main(String[] args) {
CA a = new CA();
CB b = convert(a); //this runs fine
List<CB> bl = Arrays.asList(b); //this also runs fine
List<CB> bl1 = Arrays.asList(convert(a)); //ClassCastException here
}
但是,运行它会抛出 ClassCastException: CB cannot be cast to [Ljava.lang.Object,但 CB b = convert(a) 工作正常.
However, running this throws ClassCastException: CB cannot be cast to [Ljava.lang.Object, but the CB b = convert(a) works fine.
知道为什么吗?
推荐答案
每当你创建一个带有签名的泛型方法,承诺返回调用者想要的任何东西,你就是在自找麻烦.你应该从编译器那里得到一个unchecked"警告,这基本上意味着:可能会发生意外的 ClassCastException
s.
Whenever you create a generic method with a signature that promises to return whatever the caller wishes, you are asking for trouble. You should have got an "unchecked" warning from the compiler which basically means: unexpected ClassCastException
s may occur.
您希望编译器进行推断
List<CB> bl1 = Arrays.asList(YourClass.<CA,CB>convert(a));
而编译器实际推断
List<CB> bl1 = Arrays.asList(YourClass.<CA,CB[]>convert(a));
据我所知,因为它更喜欢不需要 varargs 封装的方法调用(它与 pre-varargs 代码兼容).
as far as I know, because it prefers method invocations not requiring a varargs packaging (which is compatible with pre-varargs code).
这会失败,因为您的 convert
方法没有返回预期的数组类型.
This fails because your convert
method does not return the expected array type.
这篇关于JDK8 类型推断问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!