类加载机制 和 双亲委派机制 个人见解

类的加载机制

宏观看来就是:将一份被 javac 编译过的 class 文本文件,通过加载,生成某种形式的 Class 数据结构进入内存,程序可以调用这个数据结构构造出 object

java 类的生命周期:

在 javac 编译之后会进行如下操作

类加载的过程:

1.加载

1.1 将类的二进制字节码载入 JVM 中

1.2 将二进制字节码转换为某种静态数据结构,存放在方法区

1.3 在堆中生成一个便于用户调用的java.land.Class 对象,表示堆方法区中类的引用。

加载之后,虽然JVM内存中堆里已经存在这个对象了。但是这个时候这个对象并不被JVM认可,要想能够调用这个类,JVM需要对这个类继续连接。

  1. 连接

2.1 验证: 对class静态结构进行语法和语义上的分析,保证载入的类不会危害JVM

2.2 准备:给静态变量常量设置默认值(不包含成员变量)

2.3 解析: 将类中的符号引用转化为直接引用

​ **符号引用/直接引用:**若A引用了B,但是在编译之前A肯定不知道B的真实地址,此时将用一个字符串 S 来代替B的地址。在加载A时会触发B的类加载。此时会将A中的符号引用替换为B的实际地址。这就是直接引用。

​ **解析又分为静态解析和动态解析:**因为Java有多态机制,如果上面提到的B是一个实体类,那么这样的解析称为静态解析,如果B是一个接口或者是抽象类的时候,这个时候就没有办法确定这个引用的实际地址,既然没有那就先留着。等到运行阶段发生了调用,这个时候虚拟机中的调用栈将会得到具体的类型信息,这个时候再进行解析就可以得到明确的直接引用。这个过程就叫做动态绑定。这也是为什么解析阶段会发生在初始化阶段之后,实现后期绑定。

  1. 初始化:

    执行资源主动初始化,初始化静态常量和成员变量。而只有new 才会调用对象层面的初始化,构造函数什么的

    private Class A {
    	private int a = 1;// 初始化
    	static private int b;
    	static {
    		b = 1; //初始化
    	}
    }
    
双亲委派机制:

​ 要求除了顶层的启动类加载器之外,其余的类加载器都应该有自己的父类加载器,双亲委派在父子关系采取的并不是继承的关系,而是采用组合的关系复用父类加载器的相关代码。
(ps: 为啥叫双亲,一开始笔者也很困惑,知道发现了 双亲 的 英文叫 parent ,就大彻大悟了!我们可以将其理解为父类委派)

工作原理:

​ 如果一个类收到了类加载的请求,他并不会自己先去加载,而时将这个请求委托给父类加载器,若父类加载器还存在父类,则继续向上委托,依次递归,请求最终会到达顶层的启动类加载器。父类完成类的加载任务后,成功返回。若父类无法完成才会由子类加载器去自己加载,这就是双亲委派模式。

​ (我愿称之为 啃老机制,儿子懒,啥事都让爹干,爹也不会整了,才稀的自己动手)

优点:

  1. 类的加载具有优先级的层次关系,通过这种层级关系可以避免类的重复加载。
  2. 安全。Java核心API中定义类型不会被随意替换,假设通过网路传递一个名为java.lang.Integer的类,通过双亲委派的的模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字类,发现该类已经被加载,并不会重新加载网络传递过来的java.lang.Integer.而之际返回已经加载过的Integer.class,这样便可以防止核心API库被随意篡改。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值