如何使用java反射加载final类



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

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

相关内容

  • 没有找到相关文章

最新更新