其他分享
首页 > 其他分享> > 如何从运行时加载的类中调用构造函数?爪哇

如何从运行时加载的类中调用构造函数?爪哇

作者:互联网

我有一个类加载器,它从/ plugins文件夹中的所有jar文件中加载“主”类
这假定所有jar都具有包plugin.(插件名称),其中包含名为main的类.每个主类都有一个名为main的构造函数.

类成功加载,但是我需要知道如何从加载的类调用主构造函数.

(此类在运行时加载)

我试过使用此:

Constructor c = cls.getConstructor(Integer.class); //line 41

Plugin plug = (Plugin) c.newInstance(0);

但是我得到这个错误:

java.lang.NoSuchMethodException: plugin.myplugin.main.<init>(java.lang.Integer)  
at java.lang.Class.getConstructor0(Unknown Source)  
at java.lang.Class.getConstructor(Unknown Source)  
at hkr.classloader.PluginLoader.loadPlugins(PluginLoader.java:41)  
at hkr.core.startup.InitializeGame.inigame(InitializeGame.java:32)  
at hkr.launcher.main.LauncherMain.main(LauncherMain.java:16)  

package hackers.classloader;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import org.java.plugin.Plugin;

public class PluginLoader 
{
@SuppressWarnings({ "unused", "rawtypes", "resource" })
    public static void loadPlugins() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        Class cls = null;
        int x = hackers.core.startup.InitializeGame.map.size();
        for (int i = 1; i<=x;i++)
        {
            String className = hackers.core.startup.InitializeGame.map.get(i + "");

            File file  = new File(System.getProperty("user.dir") + File.separator + "plugins" + File.separator + className + ".jar");
            URL url = null;
            try {
                url = file.toURI().toURL();
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
            URL[] urls = new URL[]{url};
            ClassLoader cl = new URLClassLoader(urls);

            try {
                cls = cl.loadClass("plugin." + className + ".main");
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Constructor c = cls.getConstructor(Integer.TYPE);
            Plugin plug = (Plugin) c.newInstance(0);
        }
    }
}

解决方法:

如果您的构造函数采用java.lang.Integer,从我的角度来看,您的代码应该可以工作.

但是,如果构造函数的唯一参数是int,则getConstructor将失败.在这种情况下,您必须使用Integer.TYPE而不是Integer.class.
我是对的,您需要做的是:

Constructor c = cls.getConstructor(Integer.TYPE);

编辑:根据您的编辑和评论,存在一些问题.

>您要加载的类似乎没有任何显式构造函数,这意味着您只需要执行cls.getConstructor()
>您要执行的(公共静态void main)是一种静态方法,通常不需要该类的实例.另外,由于用户@Eric B解释的原因,我不确定“ main”是一个好名字.
>由于要调用方法,因此必须实例化构造函数并还要调用该方法.

根据我的理解,您想要执行的代码应该是这样的:

Constructor c = cls.getConstructor(); // we get the implicit constructor without parameters
Plugin plugin = (Plugin) c.newInstance(); // we instantiate it, no parameters

Method m = cls.getDeclaredMethod("main", Integer.TYPE);
m.invoke(plugin, 0); // we invoke the method "main" on our dynamically loaded class, with the 0 parameter.

标签:nosuchmethoderror,constructor,dynamic-class-loaders,java,classloader
来源: https://codeday.me/bug/20191127/2075095.html