java 类的加载结论三

关于ClassLoader 类的javaDoc 分析请点击

结论:

 8. 每一个类加载器的实例中都存在着一个与之相关的父类加载器,类加载器加载类或者资源时是通过使用委托机制进行的

9. ClassLoader 默认情况下是被注册支持并行的,如果在层级结构不严谨时,必须要具备并行加载类的能力,否则容易造成死锁

10. 类加载器加载类并非只从文件系统(classpath)下进行加载类,还可以从网络或者应用中构造出来的资源中进行加载,通过defineClass 方法可以将字节数组转化为Class 对象,然后调用该新类型的Class 对象通过调用 Class.newInstance() 创建新的对象

11. 自定义类加载器,通常建议重写findClass 方法,而不是重写loadClass 方法,因为loadClass 方法中实现了委托父类进行类加载的机制

12. 在重写findClass 方法时,获取到类的byte数组后,可以通过调用defineClass 方法获取到Class 对象,再通过class 对象进行实例的创建

 

/**
 * 结论:
 *      8. 每一个类加载器的实例中都存在着一个与之相关的父类加载器,类加载器加载类或者资源时是通过使用委托机制进行的
 *      9. ClassLoader 默认情况下是被注册支持并行的,如果在层级结构不严谨时,必须要具备并行加载类的能力,否则容易造成死锁
 */
public class ClassLoaderTest3 {

    public static void main(String[] args) {
        ClassLoader classLoader = ClassLoaderTest3.class.getClassLoader();
        System.out.println(classLoader);
        ClassLoader classLoaderParent = classLoader.getParent();
        System.out.println(classLoaderParent);

    }

}

以下是自定义类加载器

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

/**
 *  结论:
 *       10. 类加载器加载类并非只从文件系统(classpath)下进行加载类,还可以从网络或者应用中构造出来的资源中进行加载,通过defineClass 方法可以将字节数组转化为Class 对象,然后调用该新类型的Class 对象通过调用 Class.newInstance() 创建新的对象
 *       11. 自定义类加载器,通常建议重写findClass 方法,而不是重写loadClass 方法,因为loadClass 方法中实现了委托父类进行类加载的机制
 *       12. 在重写findClass 方法时,获取到类的byte数组后,可以通过调用defineClass 方法获取到Class 对象,再通过class 对象进行实例的创建
 */
public class ClassLoaderTest4 extends ClassLoader {

    private String classPath;//需要加载的类所在目录

    private String classLoaderName;

    private final String fileExtensionName = ".class";

    public ClassLoaderTest4(String classLoaderName,String classPath) {
        super();//指定当前类加载器的你加载器为系统类加载器
        this.classLoaderName = classLoaderName;
        this.classPath = classPath;
    }

    public ClassLoaderTest4(String classLoaderName, String classPath, ClassLoader parentClassLoader) {
        super(parentClassLoader);//指定当前类加载器的父加载器
        this.classLoaderName = classLoaderName;
        this.classPath = classPath;
    }

    private byte[] loaderClassData(String binaryName) {
        binaryName =  binaryName.replace(".","/");
        try(
//                FileInputStream fis = new FileInputStream(new File(classPath + binaryName+fileExtensionName));
                FileInputStream fis = new FileInputStream(classPath + binaryName + fileExtensionName);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ){
            int read = 0;
            while((read = fis.read()) != -1) {
                baos.write(read);
            }
            return baos.toByteArray();
        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }

    @Override
    protected Class findClass(String name) {
        System.out.println("ClassLoaderTest4 findClass invoke!");
        byte[] bytes = this.loaderClassData(name);
        return defineClass(name,bytes,0,bytes.length);
    }

    public static void main(String[] args) throws Exception {
        ClassLoaderTest4 test4 = new ClassLoaderTest4("MyClassLoader1","F:/temp/");
        Class<?> aClass = test4.loadClass("com.tanruyu.jvm.classloading.Test0");//loadClass 中如果父加载器不能加载,则会调用子类的findClass 方法进行加载类。
        System.out.println(aClass.newInstance());
//        Class<?> aClass1 = test4.findClass("com.tanruyu.jvm.classloading.Test0");
//        System.out.println(aClass1.newInstance());
    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值