4

我有一堂课

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 有 put(String s)、put(Integer i) 等。

我怎样才能做一些像动态类型转换和修复错误的事情?

4

2 回答 2

1

您在实例化 A 时提供的信息会在您将这些信息放入A<?>. 泛型只对编译器可见。

你基本上是在试图打电话someobj.put(Object o)——那是不存在的。您必须向下转换为要调用的参数类型。没有对方法的参数进行动态调度,仅在调用它的对象上进行。编译器必须准确选择要使用的方法——put(String) 或 put(Object)。这不能在运行时决定。

从理论上讲,如果您真的想在您的场景中进行动态调度,您将不得不使用访问者模式。不推荐,太麻烦了。

于 2012-05-02T08:00:26.863 回答
1

正如 Marko 所解释的,您的通用 A 的类型丢失了。但是您可以做的是使用反射来调用正确的“放置”方法。

像这样的东西:

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());
}
于 2012-05-02T08:35:40.760 回答