这里的invoke()错误:java.lang.ClassNotFoundException: class HelloWorld$Foo
,我不清楚为什么。我还不得不求助于获取字符串.class.toString()
,而不是直接使用.class
。
您是否可以帮助我调用该方法,如果还不能避免toString()
调用?
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
public class HelloWorld{
public static void main(String []args){
Map<String, Class> myMap = new HashMap<String, Class>();
myMap.put("foo", Foo.class);
myMap.put("bar", Bar.class);
try {
for(String name : myMap.keySet()){
Class<?> clazz = Class.forName(myMap.get(name).toString()); // do I need to go through string at all?
Object foobar = clazz.newInstance();
System.out.println("name: " + name + " goes " + foobar.getClass().getMethod("chirp").invoke(foobar));
}
} catch (Throwable e) {
System.err.println(e);
}
}
public abstract class Foobar {
abstract String chirp();
}
public class Foo extends Foobar {
public String chirp () { return "chirp-chirp!"; }
}
public class Bar extends Foobar {
public String chirp() {return "woof-woof!"; }
}
}
编辑:完成答案:
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
public class HelloWorld{
public static void main(String []args){
Map<String, Class> myMap = new HashMap<String, Class>();
myMap.put("foo", Foo.class);
myMap.put("bar", Bar.class);
try {
for(Map.Entry<String, Class> entry : myMap.entrySet()){
Class<?> clazz = entry.getValue();
Object foobar = clazz.getConstructor( HelloWorld.class ).newInstance( new HelloWorld() );;
System.out.println("name: " + entry.getKey() + " goes " + clazz.getMethod("chirp").invoke(foobar));
}
} catch (Throwable e) {
System.err.println(e);
}
}
public abstract class Foobar {
abstract String chirp();
}
public class Foo extends Foobar {
public String chirp () { return "chirp-chirp!"; }
}
public class Bar extends Foobar {
public String chirp() {return "woof-woof!"; }
}
}
答案 0 :(得分:3)
Foo
是HelloWorld
的内部类,因此必须由HelloWorld
的实例创建。请改为public static class Foo ...
。
如果Foo
需要是内部类(即不是static
),则需要调用相应的构造函数,例如像这样:
Foo.class.getConstructor( HelloWorld.class ).newInstance( new HelloWorld() );
请注意,以上是一个示例,因此您可能使用clazz.getConstructor(...)
。但请注意,在这种情况下,如果Bar
是一个静态的“内部”类,那么该类就没有这样的构造函数。因此,如果类不同,则必须检查哪些构造函数可用。
Class<?> clazz = myMap.get(name);
也足够了。
并注意:您不需要在循环中查找,只需迭代地图的条目集。此外,由于您创建了clazz
的实例,因此无需致电foobar.getClass()
,但可以直接使用clazz
。
for(Map.Entry<String, Class> entry : myMap.entrySet()){
Class<?> clazz = entry.getValue();
Object foobar = ...;
System.out.println("name: " + entry.getKey() + " goes " + clazz.getMethod("chirp").invoke(foobar));
}