2011-08-19 59 views
2

我试图加载final类使用follwoing代码如何使用Java反射

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

回答

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

如果失败,这意味着两两件事之一:

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

可以解决使用getDeclaredConstructor(...)代替getConstructor()第二个问题,发现构造与所有能见度:

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

第一个问题是强硬,显然:-)

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本身。它确实没有公共的构造函数,因为它并不意味着像那样被实例化。

Btw一个类或变量是final与反射或类加载问题无关。您可以随时加载一个类,只要它在类路径中找到,是公共的,并且具有公共构造函数(如果构造函数具有参数,但比上面的代码复杂一点)。

+0

'myClass.getConstructor()'如果将不利于构造函数不公开。它必须是'myClass.getDeclaredConstructor()' –

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

如果构造函数不可见,则不起作用。 –

0

您的代码工作,如果演示类有一个默认的构造函数或一个公共的无参数构造函数。 如果你有一个私人的构造函数,并尝试用它来实例化,你

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