使用反射在java中调用方法

使用反射在java中调用方法,java,reflection,Java,Reflection,我在使用java反射调用方法时遇到以下异常: 假设我有以下几类 package hello; public class SimpleService { public void SayHello(){ System.out.println("Hello World!"); } } 这个类被压缩成一个名为hello.jar的jar文件 然后,我从另一个名为TestHello.jar的jar中的另一个类调用SayHello,它是一个 简单的Swing应用程序 pu

我在使用java反射调用方法时遇到以下异常:

假设我有以下几类

package hello;

public class SimpleService {

    public void SayHello(){
        System.out.println("Hello World!");
    }
}
这个类被压缩成一个名为hello.jar的jar文件

然后,我从另一个名为TestHello.jar的jar中的另一个类调用SayHello,它是一个 简单的Swing应用程序

public class TestPanel extends javax.swing.JPanel{

.
.

jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
});

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try {
            String jarPath = "/SayHello/SayHello" + ".jar";            
            URL[] classpathURLs = new URL[]{new File(jarPath).toURI().toURL()};
            ClassLoader loader = new URLClassLoader(classpathURLs);
            Class helloClass = loader.loadClass("hello.SimpleService");           
            Method sayHello = helloClass.getMethod("SayHello");            
            int modifiers = sayHello.getModifiers();

            if (Modifier.isPublic(modifiers)) {
               sayHello.invoke(this, null);
            } else {
                throw new NoSuchMethodException();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
       }        
}


}
.
.
上面的TestPanel类也是使用java反射创建的,然后该面板将被添加到 JFrame

所有的东西都正常工作,除了我点击jButton1时,我得到以下异常

java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    .
    .
    .
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6504)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6269)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4860)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
第一个参数应该是SimpleService。将其更改为:

sayHello.invoke(helloClass.newInstance(), null);
为清晰起见,您可以如下更改代码:

sayHello.invoke(helloClass.newInstance(), (Object[]) null);
或者这个:

sayHello.invoke(helloClass.newInstance());
sayHello.invoke(helloClass.newInstance(), new Object[]{null});
否则,可能会被误解为:

sayHello.invoke(helloClass.newInstance(), (Object) null);
或者这个:

sayHello.invoke(helloClass.newInstance());
sayHello.invoke(helloClass.newInstance(), new Object[]{null});
第一个参数应该是SimpleService。将其更改为:

sayHello.invoke(helloClass.newInstance(), null);
为清晰起见,您可以如下更改代码:

sayHello.invoke(helloClass.newInstance(), (Object[]) null);
或者这个:

sayHello.invoke(helloClass.newInstance());
sayHello.invoke(helloClass.newInstance(), new Object[]{null});
否则,可能会被误解为:

sayHello.invoke(helloClass.newInstance(), (Object) null);
或者这个:

sayHello.invoke(helloClass.newInstance());
sayHello.invoke(helloClass.newInstance(), new Object[]{null});
注意这一行:sayHello.invokethis,null

使用Method.invoke时,您需要提供该方法是其实例的类的实例。因此,要调用sayHello.invoke,您需要提供一个SimpleService实例

其次,因为SayHello不接受任何参数,所以调用应该是SayHello.invokemyinstance。注意没有第二个参数。

注意这一行:sayHello.invokethis,null

使用Method.invoke时,您需要提供该方法是其实例的类的实例。因此,要调用sayHello.invoke,您需要提供一个SimpleService实例

其次,因为SayHello不接受任何参数,所以调用应该是SayHello.invokemyinstance。注意没有第二个参数。

sayHello.invoke(this, null);
此测试面板不是SimpleService的实例。您需要SimpleService的实例,或者可以将SayHello方法设置为静态:

public static void SayHello()
然后可能会传递null,以确保正确性:

为了

此测试面板不是SimpleService的实例。您需要SimpleService的实例,或者可以将SayHello方法设置为静态:

public static void SayHello()
然后可能会传递null,以确保正确性:

SayHello方法不接受任何参数,因此当反射式调用它时,除了实例之外,不要传递任何东西。此外,第一个参数应该是SimpleService的实例:

替换此项:

sayHello.invoke(this, null);
为此:

sayHello.invoke(helloClass.newInstance());
SayHello方法不接受任何参数,因此当反射式调用它时,除了实例之外,不要传递任何东西。此外,第一个参数应该是SimpleService的实例:

替换此项:

sayHello.invoke(this, null);
为此:

sayHello.invoke(helloClass.newInstance());

当然,这是TestPanel类型,而不是SimpleService类型

请尝试以下操作:

   Class helloClass = loader.loadClass("hello.SimpleService");           

   Object args1[] = new Object[] {};
   Constructor<SimpleService> constructor = helloClass.getConstructor(args1);
   Object simpleService = constructor.newInstance();       

   sayHello.invoke(simpleService, null);

当然,这是TestPanel类型,而不是SimpleService类型

请尝试以下操作:

   Class helloClass = loader.loadClass("hello.SimpleService");           

   Object args1[] = new Object[] {};
   Constructor<SimpleService> constructor = helloClass.getConstructor(args1);
   Object simpleService = constructor.newInstance();       

   sayHello.invoke(simpleService, null);

您能指定哪一行抛出该异常吗;行抛出异常。请参阅此处。这不是调用中SimpleService的实例。您可以指定哪一行引发该异常吗?sayHello.invokethis,null;行抛出异常。请参阅此处。这不是调用中SimpleService的实例,您可以直接说Object SimpleService=helloClass.newInstance.right sayHello.invokehelloClass.newInstance,null;您可以直接说Object simpleService=helloClass.newInstance.right sayHello.invokehelloClass.newInstance,null;他也在工作