我有一个班级
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)等等。
我该如何处理动态类型转换和修复错误?
答案 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());
}