2011-09-05 47 views
1

作爲What are the reasons why Map.get(Object key) is not (fully) generic的後續問題,爲什麼JDK 6和7接口沒有將「get」方法定義爲泛型方法,以便編譯器可以對返回值使用類型推斷?爲什麼JDK Map.get不支持對返回值的類型推斷

例如,如果 「GET」 被定義爲:

public <T extends V> T get(Object key) 

然後呼叫者可以這樣寫:

Map<String,Object> m = new HashMap<>(); 
m.put("key", new Foo()); 
... 
Foo f = m.get("key"); // type inference, implicit cast 

在上面的代碼片段,我可以M的定義爲Map<String,Foo>,但要注意將m定義爲Map<String,Object>而不是Map<String,Foo>在許多情況下很有用,例如,當m可以包含任何類型的值時,但仍可以基於關鍵字推斷值類型,例如一個簡單的緩存或上下文對象。

+0

這不就是同一個問題嗎?不要回答你回答這個問題的問題嗎?如果沒有,更具體。 (我最初的反應是簡單的投票結束......) –

+0

不,它不一樣。 AFAICT,這個問題已經明確地說明了這種差異,但要重申:我不是在問爲什麼鍵是Object類型的 - 這在所引用的問題中得到了回答。我在詢問如何定義get作爲類型的一般方法,這顯然是不同的。 – Raman

回答

2

因爲不這樣做(通常)是安全的。 A Map<String, Object>明確聲明其值可以是任何類型的Object,而不僅僅是Foo,因此在典型用法中,不應將其值分配給任何其他值。這樣做通常會導致程序員錯誤,類型系統應該(而且確實)幫助您避免。如果你想做那樣的事情,總會有投射,這會使你的意圖變得明確。

+0

這也是我的想法。除了投射外,另一種方法是爲特定情況創建一個不同的界面,程序員知道這個界面**可以安全地執行此操作。例如,緩存或上下文接口可以使用通用方法簽名來避免不必要的轉換,但由於Map是更一般的接口,因此不做任何不必要的假設是有意義的。 – Raman

0

在這種特定情況下,編譯器會嘗試警告您有關不安全的操作,並隱式轉換爲您需要的任何內容都被認爲是不安全的。您需要進行明確的轉換以顯示開發人員「知道」期望的類型。

Java不支持任何返回類型的類型推斷。它確定方法或表達式的返回類型,並且該賦值可能會執行隱式轉換。

我看到的唯一例外是在Java 7中添加MethodHandle.invokeExact(),並且由JVM進行特殊處理。它是一項新功能,並不適用於所有情況。 ;)

相關問題