java类加载机制-2021-11-16

java虚拟机的类加载机制

什么是类加载

java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析与初始化,最终形成可以被虚拟机直接使用的Java类型(通俗点说就是Class到对象实例的过程)

类加载的时机及初始化注意点

在这里插入图片描述
其中加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,而解析阶段在某些情况下可以在初始化阶段之后开始

类初始化阶段注意点

《java虚拟机规范严格规定了有且只有6种情况必须堆类进行初始化

  1. 遇到new、getstatic、putstatic或invokestatic字节码指令,如果类没有初始化需要先初始化
    读取或设置一个类型的静态变量(被final修饰、已在编译期就放入常量池的静态字段除外)
    调用一个类型的静态方法
public class Parents {
    static {
        System.out.println("父类初始化");
    }
    public static int num ;
}
public class Main {
    public static void main(String[] args) {
        System.out.println(Parents.num);
        //输出:父类初始化 0
    }
}

此时对静态变量进行初始化默认为0
2. 使用java.lang.reflect包的方法对类型进行反射调用
3. 子类引用父类的静态字段时,子类不会被初始化

public class Son extends Parents{
    static {
        System.out.println("子类初始化");
    }
    public static final int m = 8;

public class Main {
    public static void main(String[] args) {
        System.out.println(Son.num); //输出:父类初始化 0
//通过子类引用父类,子类不会初始化
    }
}

没有输出子类初始化,说明子类没有初始化
4. 调用类的常量(就是1中final修饰的)

public class Main {
    public static void main(String[] args) {
        //System.out.println(Parents.num);
        //输出:父类初始化 0
//        System.out.println(Son.num);
//通过子类引用父类,子类不会初始化
        System.out.println(Son.m);//输出8
//父类和子类都没有初始化
    }
}

子类和父类都没有被初始化,因为编译字段在编译过后的常量池中
5、 通过数组定义类

类加载的过程

  • 加载
    1)通过类的权限定名来得到此类的二进制字节流
    2)将字节流的静态存储转化为方法区中运行时数据结构
    3)生成一个代表此类的java.lang.Class对象,作为各种数据的入口
  • 验证确保Class文件的字节流符合规范(包括文件格式、元数据、字节码、符号引用验证)
  • 准备
    为类中变量(static变量)分配内存并设置类变量初始值
    class A{
    public static int num = 2; //这里初始化为0
    }
    final修饰为本身
  • 解析
    将常量池内符号引用替换为直接引用的过程,变成指针或者句柄定位目标(可以使用缓存invokedynamic除外)
  • 初始化
    执行类构造器()方法的过程。
    在这里插入图片描述
    在这里插入图片描述
    最后一点多条线程进行初始化只有一个线程区执行方法,其余线程都需要阻塞等待

类加载器

  • 启动类加载器
    负责加载存放在<JAVA_HOME>\lib目录,或者被-Xbootclasspath参数所指定的路径中存放的,而且java 虚拟机能够识别的
  • 扩展类加载器
    加载在类sunm.misc.Lanucher$ExtClassLoader中以java代码的形式实现的
  • 应用程序类加载器(系统类加载器)
    负责加载用户类路径上的所有类
  • 自定义类加载器

双亲委派模型

在这里插入图片描述
1、其中一个类加载器收到类加载请求,往上抛给父类加载器,父类加载器在向上抛,任何人都不愿意做,发现顶层加载不了,就向下移一个,就是执行顺序从上向下
2、收到请求的加载器最后发现自己不能加载,就不向下走,抛出ClassNotFoundException
(形象比喻-坑爹高手,爱子情深)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值