簡體   English   中英

帶有通用可變參數的 ClassCastException?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM