2011-07-30 29 views
1

我的ConverterManager上有一個概念問題。 ConverterManager是一個將類型轉換爲其他類型的對象。正如您在下面看到的,當我創建「轉換」函數時出現錯誤。泛型類的概念問題

public class StringIntegerConverter implements Converter<String, Integer> { 
    @Override 
    public Integer convert(String from) { 
     //... 
     return Integer.valueOf(from); 
    } 
} 


public class ConverterManager { 

    private static Map<Key,Converter<?,?>> converterRegistry; 
    { 
     converterRegistry = new HashMap<Key, Converter<?,?>>(); 
     converterRegistry.put(new Key(String.class, Integer.class), new StringIntegerConverter()); 
    } 

    public <T> T convert(Object source, Class<T> toType) 
    { 
     //**ERROR HERE : cause "source" is an Object** 
     return converterRegistry.get(new Key(source.getClass(),toType)).convert(source); 
    } 

} 
  • 有沒有辦法解決這個問題的方法嗎?(我不想改變我的StringIntegerConverter到accepet從對象轉換)

謝謝您的閱讀,我希望有人能幫助我;)

回答

0

基本上你就必須執行不安全的轉換 - 在執行時,JVM無法檢查您是否真的得到了Converter<String, Integer>。這留下說服它接受投入的問題。你可以做到這一點通過「代理」轉換器類,它實現Converter<Object, ?>

class ConverterConverter<T, U> implements Converter<Object, U> 
{ 
    private final Converter<T, U> original; 

    ConverterConverter(Converter<T, U> original) 
    { 
     this.original = original; 
    } 

    public U convert(Object input) 
    { 
     return original.convert((T) input); 
    } 
} 

class ConverterManager { 

    private Map<Key,Converter<Object,?>> converterRegistry; 

    ConverterManager() 
    { 
     converterRegistry = new HashMap<Key, Converter<Object,?>>(); 
     converterRegistry.put(new Key(String.class, Integer.class), 
           new ConverterConverter<String, Integer> 
            (new StringIntegerConverter())); 
    } 

    public <T> T convert(Object source, Class<T> toType) 
    { 
     Key key = new Key(source.getClass(), toType); 
     Converter<Object, ?> converter = converterRegistry.get(key); 
     return (T) converter.convert(source); 
    } 
} 

這是混亂和感覺有應該有更好的方式,但它是所有我在此刻得到了..

+0

是的,它可能是一個「好」的解決方案,謝謝! – Jarod

2

我可以看到一個「問題」 - 您的初始化程序塊不是static,而是指一個靜態字段。這意味着當它「工作」時,每當實例化類的新實例時,靜態實例將被替換。試試這個:

private static Map<Key,Converter<?,?>> converterRegistry; 
.... 
static { // ADD static KEYWORD! 
    converterRegistry = new HashMap<Key, Converter<?,?>>(); 
    converterRegistry.put(new Key(String.class, Integer.class), new StringIntegerConverter()); 
} 
... 

更優雅的選擇是一個匿名類中使用實例塊(常誤稱爲「雙支柱」初始化的時候,其實有沒有這樣的事):

private static Map<Key,Converter<?,?>> converterRegistry = new HashMap<Key, Converter<?,?>>() {{ 
    put(new Key(String.class, Integer.class), new StringIntegerConverter()); 
}}; 
+0

是的你是對的我想寫它! – Jarod