[英]ClassCastException with generic varargs?
I have a generic interface我有一个通用接口
{
void evaluate( TYPE... things );
}
I have a generic method with the signature我有一个带有签名的通用方法
<TYPE> void genericmethod( INTERFACE<TYPE> interfase, TYPE thing )
{
//the following line throws the ClassCastException
interfase.evaluate( thing );
}
PCard is a name in my project. PCard 是我项目中的一个名称。
So the call in the end is所以最后的电话是
INTERFACE<PCard> interfase = new WorkingImplementation<PCard>();
PCard pcard = new PCard();
this seems to throw a ClassCastException in the genericmethod, when it tries to call turn the single pcard into a varargs array.当它尝试调用将单个 pcard 转换为 varargs 数组时,这似乎在通用方法中抛出了 ClassCastException。
genericmethod( interfase, pcard );
The problem is relieved when there is no call to a genericmethod and you just call the interface directly.当没有调用泛型方法而您直接调用接口时,问题就得到了缓解。
interfase.evaluate( pcard );
What causes the Exception (internally)?是什么导致异常(内部)? (my personal guess is java is overwhelmed) (我个人的猜测是 java 不堪重负)
the Exception message:异常消息:
java.lang.ClassCastException: class [Ljava.lang.Object; java.lang.ClassCastException:class [Ljava.lang.Object; cannot be cast to class [Llib.cardgame.CG$PCard;不能转换为 class [Llib.cardgame.CG$PCard; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Llib.cardgame.CG$PCard; is in unnamed module of loader 'app') ([Ljava.lang.Object;在加载程序'bootstrap'的模块java.base中;[Llib.cardgame.CG$PCard;在加载程序'app'的未命名模块中)
Short answer: Generics and arrays don't mix.简短回答: Generics 和 arrays 不能混用。 Use List<? extends TYPE> things
使用List<? extends TYPE> things
List<? extends TYPE> things
instead. List<? extends TYPE> things
。
Generics are merely a compiler trick. Generics 只是一个编译器技巧。 They don't exist at runtime.它们在运行时不存在。 Arrays have a distinct type at runtime, like String[]
or Number[]
. Arrays 在运行时具有不同的类型,例如String[]
或Number[]
。 But since a generic type doesn't exist at runtime, it's not possible for the compiler to generate code that will make an array of a generic type.但是由于在运行时不存在泛型类型,编译器不可能生成将生成泛型类型数组的代码。 (A call to a varargs method creates an array implicitly to hold the varargs arguments.) (对 varargs 方法的调用会隐式创建一个数组来保存 varargs arguments。)
In your case, the compiler emits a warning about this, and generates code that's as close to what you want as possible: the generated code for the implicit array that is created whenever a varargs method is called will be Object[]
(since TYPE
, I'm guessing, has no upper bound).在您的情况下,编译器会对此发出警告,并生成尽可能接近您想要的代码:每当调用 varargs 方法时创建的隐式数组的生成代码将是Object[]
(因为TYPE
,我猜,没有上限)。
If you turn on all compiler warnings, you will be notified of this.如果您打开所有编译器警告,您将收到通知。 Addressing all compiler warnings properly (meaning, do not use @SuppressWarnings
) will guarantee that you won't get obscure surprises like the one you're getting now.正确解决所有编译器警告(意思是,不要使用@SuppressWarnings
)将保证您不会像现在遇到的那样遇到令人费解的意外。
I recommend Gilad Bracha's generics tutorial .我推荐Gilad Bracha 的 generics 教程。 I have found it invaluable for understanding how generics work.我发现它对于理解 generics 的工作原理非常宝贵。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.