【Java】JVM-自定义类加载器

Posted by 西维蜀黍 on 2019-03-07, Last Modified on 2021-09-21

自定义类加载器中的方法

findClass()

findClass() 方法是自定义类加载器类必须重写(override)的方法,用于告诉自定义类加载器到哪里去加载类,比如某个目录或者 JAR URL等。参数name 为要加载的类全名,如 java.lang.String。

该方法作为类加载的步骤之一被loadClass()方法调用。

protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
}

loadClass()

public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
}

getParent()

用于获取class loader的parent,没有返回null。

public final ClassLoader getParent()

findLoadedClass方法

返回已经加载的类。该方法直接调用本地方法实现。

protected final Class<?> findLoadedClass(String name)

自定义类加载器的例子

创建自定义类加载类

我们重写了父类的 findClass() 方法。

package com.concretepage.lang;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class CustomClassLoaderDemo extends ClassLoader {
        @Override
      public Class<?> findClass(String name) {
         byte[] bt = loadClassData(name);
         return defineClass(name, bt, 0, bt.length);
      }
      private byte[] loadClassData(String className) {
        //read class
        InputStream is = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/")+".class");
        ByteArrayOutputStream byteSt = new ByteArrayOutputStream();
        //write into byte
        int len =0;
        try {
                     while((len=is.read())!=-1){
                           byteSt.write(len);
                      }
               } catch (IOException e) {
                     e.printStackTrace();
               }
        //convert into byte array
        return byteSt.toByteArray();
     }
    
}

创建一个进行加载测试的类

package com.concretepage.lang;
public class Test {
 public void show(){
        System.out.println("Hello World!");
 }
}

创建主函数以测试自定义加载类

我们实例化一个 Test 对象,并调用其 show() 方法。

package com.concretepage.lang;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainClass {
       public static void main(String[] args) throws InstantiationException, IllegalAccessException,
                 NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

	      CustomClassLoaderDemo loader = new CustomClassLoaderDemo();
              Class<?> c = loader.findClass("com.concretepage.lang.Test");
              Object ob = c.newInstance();
              Method md = c.getMethod("show");
              md.invoke(ob);
       }
}

输出

Hello World!

Reference