这是一段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);
不是正确的方法......
答案 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);