下面是一段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的反射机制不熟悉。
BTW,我发现obj = clazz.cast(obj);
不是正确的方式…
这不起作用,因为即使在obj = clazz.cast(obj);
之后,obj
仍然只是编译器的Object
。您需要像@Peggy提到的那样显式强制类型转换:((org.abc.Test)obj).someMethod();
如果你想让它真正是动态的,你可以这样做:
if (clazz.isInstance(obj)) {
clazz.getMethod("someMethod").invoke(obj);
}
在这种情况下甚至不需要强制转换
由于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);