2011-07-30 8 views
1

私のコンバーターマネージャーに問題があります。 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); 
    } 

} 
  • この問題を解決する方法はありますか?(私はObjectから変換accepetするために私StringIntegerConverterを変更したくない)

私は、誰かが私を助けることを願っています、お読みいただきありがとうございました。)

答えて

0

基本的には、実行する必要があります安全でない変換 - 実行時に、JVMはが実際にになったことを確認できません。Converter<String, Integer>を取得しました。それは入力を受け入れるよう説得する問題を残す。

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); 
    } 
} 

これは厄介であるとより良い方法があるはずのようにそれは感じているが、それは私が現時点で持っているすべてです..:あなたはConverter<Object, ?>を実装し、「プロキシ」、コンバータクラスを経由していることを行うことができます

+0

はい、「良い」解決策になるかもしれません、ありがとうございます! – Jarod

2

イニシャライザブロックがstaticではありませんが、それは静的フィールドを参照しています。つまり、「動作する」とは、クラスの新しいインスタンスがインスタンス化されるたびに静的インスタンスが置き換えられることを意味します。

private static Map<Key,Converter<?,?>> converterRegistry = new HashMap<Key, Converter<?,?>>() {{ 
    put(new Key(String.class, Integer.class), new StringIntegerConverter()); 
}}; 
:これを試してみてください:

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()); 
} 
... 

Aよりエレガントなオプションは、匿名クラス内のインスタンスのブロックを使用することです(実際にはそのようなものが存在しない場合にしばしば誤って、「ダブルブレース」初期化子と呼ばれます)

+0

はい、私はそれを書くのが間違っています! – Jarod