簡體   English   中英

泛型的Java編譯器錯誤

[英]Java compiler error with generics

我收到此代碼的編譯器錯誤:

Map<String, String[]> myMap;

void set(Map<String, Object> foo) { }

set(myMap); // generates error

Error: "The method set(Map<String,Object>) in the type XXX is not applicable for the arguments (Map<String,String[]>)"

這對我來說毫無意義,因為String []實際上是一個對象,並且與set()中的參數完全兼容。

從我的JDK 1.6升級到1.7之前,該錯誤沒有顯示在我的代碼中。 我沒有在Eclipse中看到將其關閉的開關。 如何獲取此代碼進行編譯?

編輯:

如果使用中間變量,它會編譯,並刪除泛型:

Map anotherMap = myMap;
set(anotherMap);

泛型繼承不同於我們對OO繼承的常規理解。 請閱讀本教程

為了使您的代碼編譯,您可能需要更改方法語法,如下所示:

void set(Map<String, ?> foo) { }

編輯:正如dasblinkenlight所評論的,如果您有任何計划對set方法中的Map進行修改,則除非您定義了具體的類型,否則它將無法工作。

盡管String[]實際上是一個Object ,但這與說Map<String,String[]>實際上是Map<String,Object>並不相同:泛型的協方差不存在。

更改聲明

void set(Map<String,Object> foo) { }

帶通配符的一個

void set(Map<String,?> foo) { }

將使您的代碼編譯,並嘗試從foo映射中獲取內容將起作用:

Object blah = foo.get("key");

但是,嘗試將內容添加到地圖將失敗:

對象等等= foo.put(“ key”);

由於將事物放入地圖中似乎是您方法的目標(畢竟,一定有理由將其稱為set ),因此,如果不指定確切的類型,就無法使其工作。

在泛型中使用類型參數時,繼承的工作方式不同。

這是一個過於簡化的一般經驗法則:

在聲明和初始化通用對象時, <>的內容必須完全匹配。

也許是因為它的編譯器錯誤,Eclipse確實編譯了您的代碼。

您需要將set簽名更改為set(Map<String, ?>)以進行編譯。

它在帶有警告的第二種情況下編譯,不是嗎? 這是因為您使用原始Map(不帶泛型)來規避類型安全性檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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