Java 通过反射创建包含匿名内部类的类的对象

Java 通过反射创建包含匿名内部类的类的对象,java,reflection,inner-classes,actionlistener,Java,Reflection,Inner Classes,Actionlistener,我试图通过反射创建一个类Test的对象,该对象包含匿名内部类--ActionListener 该类已正确加载。我可以列出任何字段、方法、构造函数等。问题是,当我试图使用包含一些按钮的ActionListeners的构造函数创建对象时。当听众被评论掉时,一切都正常 当我使用Constructor.newInstance()方法时,我得到: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructor

我试图通过反射创建一个类Test的对象,该对象包含匿名内部类--ActionListener

该类已正确加载。我可以列出任何字段、方法、构造函数等。问题是,当我试图使用包含一些按钮的ActionListeners的构造函数创建对象时。当听众被评论掉时,一切都正常

当我使用Constructor.newInstance()方法时,我得到:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at Engine.createObj(Engine.java:78)
    at Main$3.actionPerformed(Main.java:107)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.IllegalAccessError: tried to access class Test.Test$2 from class Test.Test
    at Test.Test.<init>(Test.java:123)
    ... 42 more
和对象创建:

public void createObj(Constructor ct) {
    Class[] types = ct.getParameterTypes();
    //... some params generating code, not important, i'm using non-param constructor.
    try {
        object = ct.newInstance(oParams); // Here is the problem.
    } catch (Exception e) {
        e.printStackTrace();
    }
}
你写道:

    public void loadClass(File file) {
    reflectClass = null;
    try {
        FileInputStream fis = null;
        fis = new FileInputStream(file);
        byte[] bytes = new byte[fis.available()];
        int read = fis.read(bytes);
        fis.close();
        if (read != bytes.length) {
            return;
        }
        reflectClass = defineClass(null, bytes, 0, bytes.length);
        resolveClass(reflectClass);
    } catch (Exception e1) {
        e1.printStackTrace();
    }
}
此代码不能可靠地工作;仔细阅读FileInputStream.available和FileInputStream.read的JavaDoc应该可以揭示原因


可能是残缺的类文件数据导致了该异常。

让我们再来一次

因此,这是一个
IllegalAccessError
,不要与
IllegalAccessException
混淆(在JavaSE7中扩展了
ReflectiveOperationException
)。这是关于混乱的类,而不是反思


看起来好像您已经使用“自定义”类装入器装入了其中一个类,而另一个则是通过普通类装入器装入的。即使包名匹配,从不同类加载器加载的类也位于不同的包中(来自J2SE 1.2的早期更新,IIRC)。一个类试图通过“包专用”访问来访问(链接)另一个类,但JVM拒绝了它,因为包实际上是不同的。

实际上,它可能会对特定大小的文件起作用,然后神秘地失败。将文件读入字节数组的API调用可能是一个好主意。我调用的ClassLoader的默认构造函数的文档说“使用getSystemClassLoader()方法返回的ClassLoader作为父类装入器创建一个新的类装入器”。那么,它最后不应该使用“普通”类装入器吗?无论如何,我试图使用系统类加载器,但找不到任何方法从文件加载类。@dragoste系统类加载器将是父类,但它仍然是另一个类加载器。
    public void loadClass(File file) {
    reflectClass = null;
    try {
        FileInputStream fis = null;
        fis = new FileInputStream(file);
        byte[] bytes = new byte[fis.available()];
        int read = fis.read(bytes);
        fis.close();
        if (read != bytes.length) {
            return;
        }
        reflectClass = defineClass(null, bytes, 0, bytes.length);
        resolveClass(reflectClass);
    } catch (Exception e1) {
        e1.printStackTrace();
    }
}