动态型铸造?

时间:2012-05-02 07:57:40

标签: java reflection

我有一个班级

A<T> {
    T value;
    public T getValue() { return value; }
    public void setValue(T value) { this.value = value;}
}

并尝试使用非泛型方法,如下所示:

A<?>[] as = new A<?>[2]; as[0] = new A<Integer>(); as[1] = new A<String>();
for(A<?> a : as) {
    someobj.put(a.getValue()); // <-- got an error "The method put(String) is not applicable for the arguments (capture#2-of ?)"
}

someobj已经放置了(String s),put(Integer i)等等。

我该如何处理动态类型转换和修复错误?

2 个答案:

答案 0 :(得分:1)

当您将这些信息放入A<?>数组中时,您在实例化时提供的信息就会丢失。泛型仅对编译器可见。

您基本上是在尝试拨打someobj.put(Object o) - 但这不存在。您必须向下转换为您要调用的参数类型。对方法的参数没有动态调度,只对它所调用的对象进行动态调度。编译器必须准确选择将使用哪种方法 - put(String)或put(Object)。这不能在运行时决定。

理论上,如果你真的想在你的场景中进行动态调度,你将被迫使用访问者模式。我不推荐它,它非常麻烦。

答案 1 :(得分:1)

正如Marko所解释的那样,你的通用A的类型会丢失。但你可以做的是使用反射来调用正确的“put”方法。

这样的事情:

A<?>[] as = new A<?>[2]; as[0] = new A<Integer>(); as[1] = new A<String>();
for(A<?> a : as) {
    Method m = someobj.getClass().getMethod("put", a.getValue().getClass());
    m.invoke(somobj, a.getValue());
}