泛型类的概念问题

时间:2011-07-30 08:09:39

标签: java oop generics

我的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更改为从Object转换加速)

感谢您的阅读,希望有人能帮助我;)

2 个答案:

答案 0 :(得分: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()); 
}};

答案 1 :(得分: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);
    }
}

这很麻烦,感觉应该是更好的方式,但这就是我现在所拥有的一切......