[英]ClassCastException with generic varargs?
我有一個通用接口
{
void evaluate( TYPE... things );
}
我有一個帶有簽名的通用方法
<TYPE> void genericmethod( INTERFACE<TYPE> interfase, TYPE thing )
{
//the following line throws the ClassCastException
interfase.evaluate( thing );
}
PCard 是我項目中的一個名稱。
所以最后的電話是
INTERFACE<PCard> interfase = new WorkingImplementation<PCard>();
PCard pcard = new PCard();
當它嘗試調用將單個 pcard 轉換為 varargs 數組時,這似乎在通用方法中拋出了 ClassCastException。
genericmethod( interfase, pcard );
當沒有調用泛型方法而您直接調用接口時,問題就得到了緩解。
interfase.evaluate( pcard );
是什么導致異常(內部)? (我個人的猜測是 java 不堪重負)
異常消息:
java.lang.ClassCastException:class [Ljava.lang.Object; 不能轉換為 class [Llib.cardgame.CG$PCard; ([Ljava.lang.Object;在加載程序'bootstrap'的模塊java.base中;[Llib.cardgame.CG$PCard;在加載程序'app'的未命名模塊中)
簡短回答: Generics 和 arrays 不能混用。 使用List<? extends TYPE> things
List<? extends TYPE> things
。
Generics 只是一個編譯器技巧。 它們在運行時不存在。 Arrays 在運行時具有不同的類型,例如String[]
或Number[]
。 但是由於在運行時不存在泛型類型,編譯器不可能生成將生成泛型類型數組的代碼。 (對 varargs 方法的調用會隱式創建一個數組來保存 varargs arguments。)
在您的情況下,編譯器會對此發出警告,並生成盡可能接近您想要的代碼:每當調用 varargs 方法時創建的隱式數組的生成代碼將是Object[]
(因為TYPE
,我猜,沒有上限)。
如果您打開所有編譯器警告,您將收到通知。 正確解決所有編譯器警告(意思是,不要使用@SuppressWarnings
)將保證您不會像現在遇到的那樣遇到令人費解的意外。
我推薦Gilad Bracha 的 generics 教程。 我發現它對於理解 generics 的工作原理非常寶貴。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.