问题描述
这是一段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);
不是正确的方式......
1楼
这不起作用,因为obj
仍然只是编译器的一个Object
,即使在obj = clazz.cast(obj);
。
你需要一个显式的强制转换为@Peggy提到: ((org.abc.Test)obj).someMethod();
如果您想使其真正动态,您可以执行以下操作:
if (clazz.isInstance(obj)) {
clazz.getMethod("someMethod").invoke(obj);
}
在这种情况下你甚至不需要施放。
2楼
由于forName()
返回一个Class<?>
,你必须对Class<? extends Test>
执行未经检查的强制转换Class<? extends Test>
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);