类加载笔记

图片与代码引用他人,侵权请告知。

类加载的时机:

1.new关键字
2.get,set静态变量
3.反射
4.使用子类时,发现父类没有初始化时
5.调用静态方法时。
6.程序入口类。

类的加载过程:

加载,验证,准备,解析,初始化。

双亲委派模式:

1.启动类加载器:
    JAVA_HOME/lib目录下的jar
2.扩展类加载器:
    JAVA_HOME/lib/ext目录下的jar
3.应用程序类加载器:
    加载构建工具指定的classpath目录
4.自定义类加载器

从下至上,在加载前都要询问父类加载器是否可以加载。这样就保证了,父类加载的都是子类需要的基础类。当父类表示超出加载范围,那么子类再去加载。这样就保证了同一类在系统就只会出现一次。
以上的父子关系是通过组合复用父类代码实现的,不是继承实现的。

列外的情况:(不使用双亲委派模式)

热加载模式
当前线程加载器应对Native代码调用用户代码的情况。

列子:

自定义加载器的使用场景:
    当你需要加密你的字节码的时候,或者你的字节码在网络上或者数据库中时。
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class MyClassLoader extends ClassLoader
{
    public MyClassLoader()
    {

    }

    public MyClassLoader(ClassLoader parent)
    {
        super(parent);
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException
    {
        File file = new File("D:/People.class");
        try{
            byte[] bytes = getClassBytes(file);
            //defineClass方法可以把二进制流字节组成的文件转换为一个java.lang.Class
            Class<?> c = this.defineClass(name, bytes, 0, bytes.length);
            return c;
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return super.findClass(name);
    }

    private byte[] getClassBytes(File file) throws Exception
    {
        // 这里要读入.class的字节,因此要使用字节流
        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        WritableByteChannel wbc = Channels.newChannel(baos);
        ByteBuffer by = ByteBuffer.allocate(1024);

        while (true){
            int i = fc.read(by);
            if (i == 0 || i == -1)
            break;
            by.flip();
            wbc.write(by);
            by.clear();
        }
        fis.close();
        return baos.toByteArray();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值