Java 使用自定义类加载器加载静态方法

Java 使用自定义类加载器加载静态方法,java,classloader,static-methods,Java,Classloader,Static Methods,我有一个自定义类加载器,如下所示 import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class MyClassLoader extends ClassLoader { public String invoke(final String className, final String methodName, final String someString) {

我有一个自定义类加载器,如下所示

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class MyClassLoader extends ClassLoader
{
    public String invoke(final String className, final String methodName, final String someString)
    {
        try {
            final ClassLoader classLoader = getClass().getClassLoader();
            final Class loadedClass = classLoader.loadClass(className);
            final Constructor constructor = loadedClass.getConstructor();
            final Object myClassObject = constructor.newInstance();
            final Method method = loadedClass.getMethod(methodName, String.class);
            final Object testStr = method.invoke(myClassObject, someString);
            System.out.println(loadedClass.getClassLoader());
            return (String) testStr;
        }
        catch (final ClassNotFoundException e) {
            e.printStackTrace();
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
和一个名为Bus的类

public class Bus
{
    public static String connection(final String incoming)
    {
        return "Bus " + incoming;
    }
}
和一个Tester类来测试代码

public class Tester
{

    public static void main(final String[] args) throws InterruptedException
    {
        for (int i = 0; i < 3; i++) {
            final MyClassLoader mcl = new MyClassLoader();
            final String s = mcl.invoke("Bus", "connection", "awesome");
            System.out.println("Tester: " + s);
            Thread.sleep(300);
        }
    }
}
公共类测试器
{
公共静态void main(最终字符串[]args)引发InterruptedException
{
对于(int i=0;i<3;i++){
最终MyClassLoader mcl=新MyClassLoader();
最后一个字符串s=mcl.invoke(“总线”、“连接”、“很棒”);
System.out.println(“测试仪:+s”);
睡眠(300);
}
}
}
问题:为什么MyClassLoader中的sysout总是打印相同的对象(也称为类加载器)?我做错了什么


我想要实现的是,对于Tester类中的每个迭代,我希望将Bus类加载到一个新的类加载器中

您的自定义类加载器
MyClassLoader
使用
loadClass(String className)
java.lang.ClassLoader的
方法
loadClass的
方法
根据委托的原则工作,唯一性和可视性。首先,自定义的
MyClassLoader
检查父类加载器是否已加载该类。由于尚未定义MyClassLoader的父类加载器,因此需要使用getSystemClassLoader()执行
SystemClassLoader
因此,实际上,您的类是由SystemClassLoader加载的,所有对象都是由单个ClassLoader加载的。根据唯一性原则,每个类只由其父类或自身加载一次

MyClassLoader当前的工作方式:-

public class MyClassLoader extends ClassLoader
{
//supplied by compiler
   public MyClassLoader(){
   super();
   }
}
使用
SystemClassLoader
加载类的
java.lang.ClassLoader
的默认构造函数

   protected ClassLoader() {

      this.parent = getSystemClassLoader();
      initialized = true;
    }
loadClass
java.lang.ClassLoader的方法-

308     protected synchronized Class<?> More ...loadClass(String name, boolean resolve)
309         throws ClassNotFoundException
310     {
311         // First, check if the class has already been loaded
312         Class c = findLoadedClass(name);
313         if (c == null) {
314             try {
315                 if (parent != null) {
316                     c = parent.loadClass(name, false);
308受保护的同步类更多…loadClass(字符串名称,布尔解析)
309抛出ClassNotFoundException
310     {
311//首先,检查类是否已加载
312 c类=findLoadedClass(名称);
313如果(c==null){
314试试看{
315如果(父级!=null){
316 c=parent.loadClass(名称,false);

您需要实现自己的类加载器,而不仅仅是使用系统类加载器。以下是一种非常简单的方法,仅当类文件位于预期目录中时才有效

public class MyClassLoader extends ClassLoader
{
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        try {
            byte b[] = Files.readAllBytes(Paths.get("target/classes/"+name+".class"));
            ByteBuffer bb = ByteBuffer.wrap(b); 
            return super.defineClass(name, bb,null);
        } catch (IOException ex) {
            return super.loadClass(name);
        }
    }


    public String invoke(final String className, final String methodName, final String someString)
    {
        try {
            final ClassLoader classLoader = this;
公共类MyClassLoader扩展了ClassLoader
{
@凌驾
公共类loadClass(字符串名称)引发ClassNotFoundException{
试一试{
字节b[]=Files.readAllBytes(path.get(“target/classes/”+name+“.class”));
ByteBuffer bb=ByteBuffer.wrap(b);
返回super.defineClass(name,bb,null);
}捕获(IOEX异常){
返回super.loadClass(名称);
}
}
公共字符串调用(最终字符串类名称、最终字符串方法名称、最终字符串someString)
{
试一试{
最终类加载器类加载器=此;

由于委托原则,您的类由SystemClassLoader而不是MyClassLoader加载。