2013-10-05 20 views
0

我正在爲JSON Jackson pojo序列化/反序列化編寫包裝器。 所以我試圖寫一個通用的方法,將返回一般反序列化的對象。通用方法中的通用參數返回值

我覺得代碼可以解釋這更好:

public <K,V, M extends Map<K, V>> M readMap(String path, Class<M> mapType, Class<K> keyClass, Class<V> valueClass) throws JsonParseException, JsonMappingException, IOException 
{ 
    ObjectMapper mapper = new ObjectMapper(); 
    return mapper.readValue(new File(path), mapper.getTypeFactory().constructMapType(mapType, keyClass, valueClass)); 
} 

代碼

HashMap<String, Double> weightMap; 
JSONParsedFileHandler reader = new JSONParsedFileHandler(); 
weightMap = reader.readMap("weights.model", HashMap.class, String.class, Double.class); 

可正常工作,但是,我得到一個類型安全警示:

Type safety: The expression of type HashMap needs unchecked conversion to conform to HashMap<String,Double> 

我認爲這意味着返回的類型與預期一樣,除非它沒有按照我編碼進行參數化。

有沒有人有任何想法?

回答

1

constructMapType方法返回MapType,它使用Class<?>來定義密鑰和內容。使用類型擦除基本上轉換爲Object,並且編譯器無法告訴地圖中使用哪些類型。類型「參數化爲(您)編碼的」,但Java的泛型實現阻止了您提供的類型的任何運行時知識。有人糾正我,如果我錯了,但我相信你只有選擇是處理警告或壓制它。

+0

感謝您的回答... –

+0

有沒有辦法避免醜陋@SuppressWarning標籤? –

+0

我不這麼認爲。雖然比警告更漂亮,對吧? – Dave

1

嘗試邊界只是地圖的類,然後從K和V僅聲明返回類型:

public <K,V, M extends Map<?, ?>> Map<K, V> readMap(String path, Class<M> mapClass, Class<K> keyClass, Class<V> valueClass) throws JsonParseException, JsonMappingException, IOException { 
    ObjectMapper mapper = new ObjectMapper(); 
    return mapper.readValue(new File(path), mapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass)); 
} 
+0

這個解決方案實際上迫使方法的調用者進行轉換(你必須明確地從Map轉換爲HashMap)。我試圖做通用返回類型的原因是爲了避免它。 –

+1

最佳做法是調用者(實際上所有的代碼)不應該將變量類型聲明爲HashMap(實現),而只需要Map(抽象類型),因爲它的實現無關緊要 - 它只是重要的一張地圖。參見[Liskov替代原則](http://en.wikipedia.org/wiki/Liskov_substitution_principle)。如果您將變量聲明爲Map ,您將擁有更好的代碼並且不需要投射。 – Bohemian

+0

這是真的 - 但它不會使警告消失:)但它是一個很好的提示。 –