我正在尝试使用以下代码加载最终类
final ClassLoader myClassLoader = ClassLoader.getSystemClassLoader();
final String classNameToBeLoaded = "demo";
final Class myClass = myClassLoader.loadClass(classNameToBeLoaded);
// create a new instance
final Constructor cons = demo.class.getConstructor();......(1)
final Object whatInstance = cons.newInstance();
它没有返回这样的方法异常…在1。有什么问题吗?
在没有看到所讨论类的实际定义的情况下,我们只能猜测该类可能没有公共默认(无参数)构造函数。
实际上,问题似乎是您试图获得类Class
的构造函数,而不是实际的类:
final Class myClass = myClassLoader.loadClass(classNameToBeLoaded);
// create a new instance
final Constructor cons = demo.class.getConstructor();......(1)
最后一行的方法调用应该改为myClass.getConstructor()
: myClass
引用Class
类型的对象,这是demo
类的类令牌。因此,反过来,myClass.class
引用myClass
的类令牌,即Class
类本身。它确实没有公共构造函数,因为它不打算像那样被实例化。
顺便说一句,一个类或变量被final
与反射或类加载问题无关。你总是可以加载一个类,只要它在类路径上,是公共的,并且有一个公共构造函数(如果构造函数有参数,那么它比上面的代码要复杂一点)。
final Constructor cons = demo.class.getConstructor();
如果失败,这意味着两种情况之一:
要么没有默认构造函数,要么不是公共的(class.getConstructor(...)
只返回公共构造函数,如果有公共默认构造函数,您就不会首先这样做)。
你可以通过使用getDeclaredConstructor(...)
而不是getConstructor()
来解决第二个问题,它可以找到具有所有可见性的构造函数:
final Constructor<Demo> cons = demo.class.getDeclaredConstructor();
Demo demo = cons.newInstance();
第一个问题显然更难:-)
try {
Object instance = Class.forName("com.foo.Demo").newInstance();
} catch(ClassNotFoundException e) {
// do something
}
如果演示类具有默认构造函数或公共无参数构造函数,则代码可以正常工作。如果您有一个私有构造函数并尝试使用它进行实例化,则会得到
java.lang.IllegalAccessException: Class ... can not access a member of class demo with modifiers "private"
你只需要使用合适的构造函数。
假设你的类有一个接受int形参的公共构造函数:
public final class Demo {
private final int i;
public Demo(int i) {
this.i = i;
}
public void doSmth() {
System.out.print("Your number is: " + i);
}
}
这里是主类:
import java.lang.reflect.Constructor;
public class Main {
public static void main(String[] args) throws Exception {
final ClassLoader myClassLoader = ClassLoader.getSystemClassLoader();
final String classNameToBeLoaded = "Demo";
final Class myClass = myClassLoader.loadClass(classNameToBeLoaded);
// create a new instance
final Constructor cons = Demo.class.getConstructor(int.class);
int i = 10;
final Object whatInstance = cons.newInstance(i);
// prints: Your number is: 10
((Demo) whatInstance).doSmth();
}
}