2014-01-27 40 views
0

我會以某種方式在HashMap中存儲許多不同類型,但以一種方式,當我提取它們時,它們將很好地鍵入(而不是一個對象)。Java:類包裝使用泛型

所以我想使用泛型

public class Value <T> 
{ 
    private T innerValue ; 

    public Value (T _value) 
    { 
     innerValue = _value ; 
    } 

    public T read() 
    { 
     return innerValue ; 
    } 
} 

的包裝,但它不工作,對於測試我做:

Value <Integer> va = new Value <Integer> (1) ; 
Value vc = va ; 
int restA = vc.read(); 

,但我得到一個設計時錯誤,因爲VC。 read()將返回一個Object()而不是一個Integer。 那麼我該怎麼做才能避免這種行爲? (如果可能的話,我會解決方案,防止'VA'丟失有關T的信息,而不是其他解決方法)

在此先感謝您的任何幫助。

+0

不幸的是,我不相信這將是可能做到這一點,直到一些未來的Java版本中,泛型是「具體化」和參數Java中的類型不再使用擦除來實現。 –

+0

@DavidConrad我不相信會發生。 – bdrx

+0

很傷心。 因此,出於同樣的原因,沒有辦法將對象直接反序列化到正確的類型,這是正確的嗎? – Skary

回答

2

您將va鑄造成原料Value,vc。當您使用一個類的原始形式時,您的T泛型類型參數被替換爲Object。所以你不能將Object分配給int

如果你只是打電話給va.read(),那麼它將返回一個Integer,在分配到restA後,它將被拆箱到int

+0

所以我想所有Value的實例,存儲在HashMap中,以相同的方式失去它們的泛型類型。 (並且我不能將所有可能的類型映射到這個HashMap中)。有什麼方法可以將T存儲在Value的實例的私有字段中? – Skary

+0

您可以存儲一個'Class ',但僅僅讓'Object'作爲'HashMap'的值類型,你會得到很少的結果,因爲在將它轉換爲訪問類之前,你仍然必須測試它的類型,無論如何,具體方法。 – rgettman

1

我會以某種方式儲存許多不同類型的一個HashMap中,但在 方式,當我提取他們,他們會得到很好類型(而不是一個 對象)。

簡短的回答是:這是不可能的。並且類型擦除不是原因:在編譯時獲得這些信息沒有多大意義。假設Java編譯器有某種機制來跟蹤填充到HashMap中的對象的類型。那麼它也將不得不應對這樣的事情:

HashMap<Integer, Value<?>> myMap = new HashMap<Integer, Value<?>>; 
if (Math.random() > 0.5) { 
    myMap.put(0, new Value<String>("hello world")); 
} else { 
    myMap.put(0, new Value<MacaroniExtruder>(new MacaroniExtruder())); 
} 
[whatDoYouWantToWriteHere?] value = myMap.get(0); 

你想要的可能是像「type-union」。不幸的是,它既不存在於Java中,也不存在於Scala中(我們有案例類,這幾乎同樣適用)。所以你可以做的基本上是:

A)使用多態,定義一個合適的接口,使具體的實現變得完全不相關,並使用該接口作爲散列Map(首選)的第二個參數。

B)使用的instanceof和長期的if-else開關(醜)