动态将对象强制转换为特定类以使用函数

时间:2015-07-17 13:32:31

标签: java generics reflection

这是一段java代码,我们假设org.abc.Test是一个接口。

for (Object obj : objectArray[]) {
    if (obj instanceof org.abc.Test) {
        ((org.abc.Test)obj).someMethod();
    }
}

现在假设类org.abc.Test作为String动态传递,代码可能是这样的:

String className = "org.abc.Test";
Class<?> clazz = Class.forName(className);
for ( Object obj : objectArray[]) {
    if (clazz.inInstance(obj)) {
        obj = clazz.cast(obj);
        obj.someMethod();
    }
}

不幸的是,语句obj.someMethod();无法通过编译,因为编译器在转换后不知道对象的特定类。

所以我认为应该使用这样的声明:

Class<? extends org.abc.Test> clazz;

有人可以帮忙解决这个问题吗?我只是java反射机制的新手。

顺便说一句,我发现obj = clazz.cast(obj);不是正确的方法......

2 个答案:

答案 0 :(得分:3)

这不起作用,因为obj仍然只是编译器的Object,即使在obj = clazz.cast(obj);之后也是如此。你需要一个明确的演员,提到@Peggy:((org.abc.Test)obj).someMethod();

如果您想让它真正动态,您可以执行以下操作:

if (clazz.isInstance(obj)) {
    clazz.getMethod("someMethod").invoke(obj);
}

在这种情况下,你甚至不需要施放。

答案 1 :(得分:3)

由于forName()返回Class<?>,您必须执行未经检查的转换为Class<? extends Test>。有了这个,您的代码就可以工作(只需要一些小的修正):

String className = "org.abc.Test";
Class<? extends Test> clazz = (Class<? extends Test>) Class.forName(className);
for ( Object obj : objectArray) {
    if (clazz.isInstance(obj)) {
        clazz.cast(obj).someMethod();
    }
}

正如@epoch在评论中指出的那样,你也可以使用asSubclass()摆脱演员阵容:

Class<? extends Test> clazz = Class.forName(className).asSubclass(Test.class);