2008-10-27 37 views
14

我延長在庫中定義的類,我不能改變:使用原始類型參數覆蓋方法時可以避免未經檢查的警告嗎?

public class Parent 
{ 
    public void init(Map properties) { ... } 
} 

如果我定義一個類「兒童」,擴展父母和我使用的Java 6泛型,什麼是最好的方式重寫init方法而不會收到未經檢查的警告?

public class Child extends Parent 
{ 
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized 
    public void init(Map properties) { } 
} 

如果我添加泛型參數,我得到:不管我是否使用特定類型,綁定的通配符,或者無界通配符發生

// error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it 
    public void init(Map<Object,Object>) { ... } 
    // same error 
    public void init(Map<? extends Object,? extends Object>) { ... } 
    // same error 
    public void init(Map<?,?>) { ... } 

此錯誤。有沒有一種正確或慣用的方法來覆蓋非警告的非泛型方法,並且不使用@SuppressWarnings(「unchecked」)?

回答

12

是的,你必須聲明具有相同簽名的首要方法,在父類,不添加任何仿製藥信息。

我認爲最好的方法是將@SuppressWarnings("unchecked")註釋添加到原始類型參數中,而不是方法,因此您不會壓制在您自己的代碼中可能存在的其他仿製藥警告

+0

@SuppressWarnings絕對是您在這裏最好的選擇。吮吸,但是當你試圖強制泛型進入不使用它的庫時會發生這種情況。 – 2008-10-28 02:52:56

2

簡答:沒辦法做到這一點。

Unsatisfying answer:禁用IDE/build.xml中的(特定)警告。

如果你不能改變庫,唉,你必須堅持使用非泛型方法。

問題是,儘管類型擦除後兩個init()具有相同的簽名,但它們可能實際上是不同的方法 - 或相同的(*)。編譯器無法確定它是否應該覆蓋或超載,因此它是被禁止的。

(*) 假設庫開發人員的意思是init(地圖<字符串,整數>)。現在你正在執行init(Map < String,String >)。這是重載,並且在Child類的vtable中應該存在兩種方法。

但是,如果庫開發人員意味着初始化(地圖<字符串,字符串>)呢?然後重寫,你的方法應該用代替 Child類中的原始init,並且在Child的vtable中只有一個方法。

P.S.我討厭泛型在Java中如何實現:-(

+0

您能解釋一下爲什麼具有相同(擦除)簽名的方法可能是編譯器的不同方法?編譯器在編碼時不知道開發人員_meant_ ...--) – nrainer 2015-05-28 08:34:44

0

您必須聲明與父級相同的簽名方法,因此在編譯時會得到警告,你可以用@SuppressWarnings(「unchecked」)來壓制它們。

爲什麼沒有辦法擺脫這種情況的原因是,警告在那裏讓你知道有可能創建具有無效類型的集合。只有當所有可能允許刪除的代碼被刪除時,警告纔會消失。由於您從非泛型類繼承,因此始終可以使用無效內容創建集合。

2

我認爲上面的答案意味着說@SuppressWarnings(「rawtypes」)。

相關問題