2011-02-01 41 views
5

已經有幾次當我覺得有必要做一些這樣的:的Java界通用的制約領域

private <T extends Type> Map<GenericClass1<T>,GenericClass2<T>> map; 

...或者諸如此類的話。實質上,在map的兩個參數中使用相同的邊界。 (這不是一個實際的例子,只是給出了這個概念。)

我知道這(不幸)是不可能的,這只是在類的定義和方法簽名可用。然而,我的問題是爲什麼它不在字段上?是純粹的設計選擇還是背後有一些技術原因,我錯過了?我已經有了一個想法,並且不知道爲什麼從技術角度來看這是不可能的,就我所能看到的一切來說,編譯器可以正確地解決它,並且在運行時不需要任何通用信息。

回答

1

<Ť>指一類,而不是A類。 當你的對象被實例化時,T被綁定到這個ONE類。

您試圖將具有不同接口的兩個對象(由於它們採用/返回不同類型而不同地使用)放入同一個容器中。這是一個錯誤,因爲當你帶他們出去,你不知道這是什麼容器(地圖),你投入。

希望這是你要找的答案。

編輯:那就是說你可以有保持基於有類成員的容器,自動爲每個類型T,那麼你需要知道什麼T爲以訪問一個新的地圖。一般來說,如果你不再需要類型信息,就把它扔掉。如果你真的把它放在同一個容器中,而其他類型的東西則會因爲所有的實際原因而將它扔掉。

+0

@「在運行時不需要任何通用信息」,如果編譯器允許您在運行時根據可能的情況執行某些操作,則語言不會再輸入。鍵入是限制。 – mncl 2011-02-01 11:09:35

0

可以使用?如下:

private List<? extends List> l = new ArrayList<List>();

我希望這有助於。

+0

感謝您的回答,但這不是我所追求的 - 我知道我可以使用基本的通配符,但我想要捕捉跨越多個通用參數的完全相同的界限(在問題中爲T)。我可以使用「?extends Type」兩次,但不能保證有相同的邊界,它可能是兩個不同的類,它們擴展了Type。 – berry120 2011-02-01 10:42:17

1

我們假設你想實例化你的map變量。理論上你必須寫這樣的東西:

map = new HashMap<GenericClass1<String>,GenericClass2<String>>(); 

好的。但現在什麼對我來說沒有意義是什麼論點putget方法將接受/返回? T?呃...什麼是TGenericClass1|2<String>?再次沒有意義,是嗎?畢竟我在map聲明中看不到String。所以我猜這個泛型變量沒有真正正確的實例和用法。

乾杯!

1

哦,我怎麼一直渴望這樣的事情:

private <T> Map<Class<T>, T> instanceCache; 

public <T> T getInstanceOf(Class<T> clazz) { 
    return instanceCache.get(clazz); 
} 

但正如你所說,它在Java中是完全不可能的。上面的方法聲明是好的,但是沒有辦法聲明變量,使得方法中沒有強制轉換。只需將其添加到越來越多的您討厭仿製藥並且繼續前進的事物中。