java类加载

类加载

反射加载是Java实现动态语言的关键,也就是通过反射实现类的动态加载

静态加载

编译时加载相关的类,如果没有则报错,依赖性太强

动态加载

运行时加载需要的类,如果运行时不用该类就不报错,降低了依赖性。反射就是动态加载。

静态加载动态加载的示例

静态加载

在这里插入图片描述

动态加载

在这里插入图片描述

类加载时机

1、当创建对象时(new) //静态加载

2、当子类被加载时,父类也加载 //静态加载

3、调用类中的静态成员时 //静态加载

4、通过反射 //动态加载

Java程序在计算机中有三个阶段

在这里插入图片描述

类加载过程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ra2Cucl-1662304781487)(C:\Users\wu\AppData\Roaming\Typora\typora-user-images\image-20220904162804770.png)]
在这里插入图片描述

类加载的各个阶段解释
加载阶段

JVM在该阶段的主要目的是将字节码从不同的数据源(可能是class文件、也可能是jar包、甚至是网络)转化为二进制字节流加载到内存中,并生成一个代表该类的java.lang.Class对象

连接阶段—验证

1、目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会威胁到虚拟机自身的安全

2、包括:文件格式的验证(类的二进制数据是否以魔数 0X cafebabe(16进制数字)开头,是则合法)、元数据验证、字节码验证和符号引用验证。

3、可以考虑使用-Xverify:none参数来关闭大部分的类验证措施,缩短虚拟机加载的时间

连接阶段—准备

1、JVM会在该阶段对静态变量,分配内存并默认初始化(对应数据类型的默认初始值,如0,null,false等)这些变量所使用的内存都将在方法区中进行分配

class A{
    //1、n1是实例变量,不是静态变量,因此在准备阶段是不会分配内存
    //2、n2是静态变量,分配内存 n2是默认初始化0,而不是20
    //3、n2是静态常量,和静态变量不同,一旦赋值就不能再改变了,n3=30
    public int n1=10;
    public static int n2=20;
    public static final int n3=30;
}
连接阶段—解析

虚拟机将常量池中的符号引用替换为直接引用的过程

就是将类的引用变为为在内存中的地址

Initalization初始化阶段

1、到初始化阶段,才真正开始执行类中定义的Java程序代码,此阶段是执行<clinit>()方法的过程

2、<clinit>()方法是由编译器按照语句在源文件中出现的顺序,依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并进行合并

3、虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确的加锁、同步,如果多个线程同时去初始化一个类,那么只有一个线程去执行这个类的<clint>()方法,其他线程都需要阻塞等待,知道活动线程执行<clint>()方法完毕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值