【JVM2】类装载子系统

在这里插入图片描述
类加载器加载.class具体还要成三步:

一、加载

生成代表该类的Class实例

二、链接在这里插入图片描述

1、验证:主要是验证字节码文件无误,因为字节码文件是可以被认为修改的。
2、准备:准备阶段会进行默认初始化,如下代码:

public class Test01 {
    private int i=88;
    public static void main(String[] args) {
    }

}

默认初始化就是在准备阶段先把 i 赋值为0,当然如果是String类型就是null;
3、解析

三、初始化

在这里插入图片描述
这里解释一下初始化的最后一点:需要new 一个类时,这个类就会被加载,在类加载的初始化阶段就会调用类构造器的方法,如果两个线程同时new,那么就需要排队访问方法。

public class DeadThreadTest {
    public static void main(String[] args) {
        Runnable runnable=()->{
            System.out.println(Thread.currentThread().getName()+"开始");
            DeadThread deadThread = new DeadThread();
            System.out.println(Thread.currentThread().getName()+"结束");
        };
        new Thread(runnable,"线程1").start();
        new Thread(runnable,"线程2").start();
    }

}
class DeadThread{
    static {
        if(true){
            System.out.println(Thread.currentThread().getName()+"正在加载DeadThread");
            while (true){

            }
        }
    }
}

因为方法是收集类变量和合并static代码块,所以当static代码块发生死循环时,一个线程就一直占着锁,另一个线程访问不了方法。

类加载器分类

在这里插入图片描述

在这里插入图片描述扩展类加载器和系统类加载器都间接继承了ClassLoder这个类,所以他们两个都为自定义类加载器,如果我们写个类继承ClassLoder类,那么也为自定义类加载器。引导类加载器是由C++写的,自定义类加载器都是用java写的,所以可以从代码层面看到自定义类加载器,而引导类加载器看不到。

//1、获取类的类加载器
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {

        //1、获取系统类的类加载器,负责我们写的一些类-----如负责Java-classpath或java.class.path目录下的类或jar包的装入工作
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //2、获取扩展类的类加载器<——系统类的类加载器的父类加载器----负责jre/lib/ext目录下的jar包等
        ClassLoader ext = systemClassLoader.getParent();
        System.out.println(ext);

        //3、获取根加载器<——扩展类的类加载器的父类加载器
        //由于根加载器是由C++编写的,负责Java的核心库的。
        ClassLoader parent = ext.getParent();
        System.out.println(parent);

        //测试用户自定义类是哪个类加载器加载的
        ClassLoader classLoader = Class.forName("com.yiheng.yiheng_03_classLoder.Test03").getClassLoader();
        System.out.println(classLoader);
        //测试JDk内置类-Java核心类是哪个加载器加载的
        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1);

        //测试系统类的jar包会从些目录加载
        System.out.println(System.getProperty("java.class.path"));
        /*
        E:\JAVA\Java\jdk-1.8\jre\lib\charsets.jar;
        。。。
        。。。
        E:\JAVA\Java\jdk-1.8\jre\lib\rt.jar;
        E:\JavaSE\Base\javaBase-02-AnnotationAndreflection\target\classes;
        E:\JAVA缓存文件\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar
        */
    }
}
结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1b6d3586
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null

可以看出Java核心类是由引导类加载器加载的,而且扩展类加载器和系统类加载器也是一个类,它们两个加载器都是由引导类加载器加载的。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用户自定义类加载器

目的:
隔离加载类
修改类的加载方式
扩展加载源
防止源码泄露(加密解密)

关于ClassLoder类

1、它是一个抽象类,所有类加载器(不包括引导类加载器)都继承字它

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值