2011-09-15 57 views
9

我想創建一個接口:是否有可能使用泛型返回類型定義接口方法,並且具體實現是否定義了返回類型?

public interface OperandValue 
{ 
    <T> T getValue(); 
} 

然後,我會希望有一個具體的實現是這樣的:

public class NumberOperandValue implements OperandValue 
{ 
    @Override 
    public <Integer> Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

Eclipse是強調了<Integer>給我,說一個警告:

類型參數Integer隱藏類型整數

我很欣賞任何建議,如果這可以以某種方式工作。我意識到我可以在接口級別而不是方法級別定義泛型類型,但是想盡可能地使其工作。

回答

22

你可能想接口更改爲:

public interface OperandValue<T> 
{ 
    T getValue(); 
} 

而實施:

public class NumberOperandValue implements OperandValue<Integer> 
{ 
    @Override 
    public Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

現在你告訴界面你想這個方法返回什麼類型。換句話說,你使接口類型是泛型的,而不是方法聲明。但那似乎是你想要的。

補充說明:

public <Integer> Integer getValue() 

實際上意味着,「定義名稱爲‘整數’泛型類型參數」,其中getValue返回「整數」類型剛剛定義

迴應史蒂夫的評論下面

,當我從我的方法實現去除<Integer>我再 得到,說一個警告:Type safety: The return type Integer for getValue() from the type NumberOperandValue needs unchecked conversion to conform to T from the type OperandValue

該警告消息表明您在使用Java泛型時會違反規則。爲了明白爲什麼,讓我們先考慮方法簽名的含義,然後再刪除<Integer>類型參數。

public <Integer> Integer getValue() 

這個簽名意味着getValue返回Integer類型,其中Integer被定義爲你的尖括號之間所界定的一般類型參數的值的方法。字符串Integer的意義完全是任意的,將具有完全相同的含義相同:

public <T> T getValue() 

爲了清楚起見,讓我們堅持這個版本的方法簽名爲你的問題的目的。當我們移除類型參數時會發生什麼?

public T getValue() 

現在,如果你嘗試編譯,你會得到一個錯誤,T是不確定的。然而,因爲你原來的類型簽名中聲明的名稱Integer類型參數,當你刪除它,你留下了:

public Integer getValue() 

因爲Integer已經預定義的類型,方法簽名仍然是技術上是合法的。然而,你的類型參數的名稱恰好與已經存在的類型相同,這只是偶然的。

此外,由於您的接口已經聲明瞭方法簽名泛型,因此Java編譯器在將其從實現中移除時會生成警告。具體來說,編譯器擔心在基類中,方法的返回類型是(類型擦除到Object)名爲Integer的通用參數,該參數不是相同類型(也不知道與類型兼容)系統類名爲Integer(或準確地說是java.lang.Integer)。

+0

是否有可能有一個接口方法本身通用?如果是這樣,你將如何實現它? – Kal

+1

@卡爾,是的,這是可能的。但是在實現類中「插入」特定類型是不可能的。如果方法是泛型的,這意味着方法的*調用者*負責提供類型參數。 –

+0

謝謝柯克。我懂了。如果接口定義是由OP定義的,那麼實現應該定義爲'@Override public T getValue()'。正確? – Kal

相關問題