动态类型转换是什么?

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)等方法。

我该如何进行动态类型转换并纠正错误?

2个回答

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

1

一旦您将其放入 A<?> 数组中,实例化 A 时提供的信息就会丢失。泛型只对编译器可见。

您基本上要尝试调用 someobj.put(Object o),但它不存在。您必须向下转换为您希望调用的参数类型。方法的参数没有动态分派,只有在调用该方法的对象上进行动态分派。编译器必须精确选择要使用的方法,即 put(String) 或 put(Object)。这不能在运行时决定。

理论上,如果您真的想在您的场景中进行动态分派,您将被迫使用访问者模式。我不建议这样做,这非常麻烦。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接