如何使用java反射加载final类

时间:2011-08-19 07:41:45

标签: java reflection

我正在尝试使用以下代码加载最终类

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.问题是什么......?

4 个答案:

答案 0 :(得分:2)

如果没有看到相关类的实际定义,我们只能猜测该类可能没有公共默认(无参数)构造函数。

实际上,问题似乎是你试图获得类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与反射或类加载问题无关。你可以随时加载一个类,只要它在类路径中找到,是公共的,并且有一个公共构造函数(如果构造函数有参数,它比上面的代码复杂一点)。

答案 1 :(得分:1)

final Constructor cons = demo.class.getConstructor();

如果失败,这意味着以下两点之一:

要么没有默认构造函数,要么它不是公共的(class.getConstructor(...)只返回公共构造函数,如果有公共默认构造函数,则首先不会这样做)。

您可以使用getDeclaredConstructor(...)代替getConstructor()来解决第二个问题,它会找到具有所有可见性的构造函数:

final Constructor<Demo> cons = demo.class.getDeclaredConstructor();
Demo demo = cons.newInstance();

第一个问题更严厉,显然: - )

答案 2 :(得分:0)

try {
    Object instance = Class.forName("com.foo.Demo").newInstance();
} catch(ClassNotFoundException e) {
    // do something
}

答案 3 :(得分:0)

如果demo类具有默认构造函数或公共无参数构造函数,则代码可以正常工作。 如果你有一个私有构造函数并尝试使用它来实例化,你得到

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);
    }
}

这里是 Main 类:

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();
    }
}