Java类的加载过程-重点!!
java类的加载过程有以下几步共同完成:
加载->连接->初始化。连接又分为验证、准备、解析
一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass() 方法)。
数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。
JVM 中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader。
BootstrapClassLoader(启动类加载器) :最顶层的加载类,(JNI :java本地接口)由C++实现,负责加载 %JAVA_HOME%/lib目录下的jar包和类或者或被 -Xbootclasspath参数指定的路径中的所有类。
ExtensionClassLoader(扩展类加载器) :主要负责加载目录 %JRE_HOME%/lib/ext
目录下的jar包和类,或被 java.ext.dirs 系统变量所指定的路径下的jar包。AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用classpath下的所有jar包和类。
双亲委派机制:
每一个类都有注解的类加载器。系统中的Classloader在协同工作的时候回默认使用双亲委派机制。再类加载的时候,系统会首先判断当前类的是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派给父类的加载器的loadClass()处理,因此所有的请求最终都应该传送到顶层的启动类的加载器BootstrapClassLoader。当父类加载器无法处理时,才交给自己处理,当父类加载器是null时,会使用类加载器bootstrapClassLoader作为父类加载器。
双亲委派模型实现源码分析
private final ClassLoader parent;
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先,检查请求的类是否已经被加载过
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {//父加载器不为空,调用父加载器loadClass()方法处理
c = parent.loadClass(name, false);
} else {//父加载器为空,使用启动类加载器 BootstrapClassLoader 加载
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
//抛出异常说明父类加载器无法完成加载请求
}
if (c == null) {
long t1 = System.nanoTime();
//自己尝试加载
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
- 其实这个双亲翻译的容易让别人误解,我们一般理解的双亲都是父母,这里的双亲更多地表达的是“父母这一辈”的人而已,并不是说真的有一个 Mother ClassLoader 和一个 Father ClassLoader 。另外,类加载器之间的“父子”关系也不是通过继承来体现的,是由“优先级”来决定。
双亲委派机制的好处
双亲委派模型保证了Java程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载自己加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object 类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类。
如果我们不想用双亲委派模型怎么办?
为了避免双亲委托机制,我们可以自己定义一个类加载器,然后重写 loadClass() 即可。
自定义类加载器
除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader。如果我们要自定义自己的类加载器,很明显需要继承 ClassLoader。
Java类的加载过程-重点!!的更多相关文章
- JAVA - 类的加载过程
JAVA - 类的加载过程 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象 ...
- Java类的加载过程与ClassLoader的理解及测试
当程序准备运行某个类,但该类还未被加载到内存中时,会经过以下三个步骤进行类的加载: 类的加载(Load)→类的连接(Link)→类的初始化(Initialize) 加载:类经过javac.exe编译的 ...
- java类的加载过程
1.类的加载顺序 (1)JVM在首次加载类时会对 静态初始化块.静态成员变量. 静态方法进行一次初始化. (2)只有在调用new方法时才会创建类的实例. (3)对象创建过程: 首先执行父类(如果有) ...
- Java 类的加载过程(阿里面试题)
问以下程序打印出什么内容: 问题及解析如下: /** * 加载方法不等于执行方法,初始化变量则会赋值 * 类加载顺序应为 加载静态方法-初始化静态变量-执行静态代码块 * 实例化时 先加载非静态方法- ...
- Java类的加载、链接和初始化
一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...
- java类从加载、连接到初始化过程
类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个Class对象,存储在.class文件中,JV ...
- java 反射,类的加载过程以及Classloader类加载器
首先自定义一个类Person package reflection; public class Person { private String name; public int age; public ...
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
- Dubbo源码解析之SPI(一):扩展类的加载过程
Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...
随机推荐
- Kruskal重构树——[NOI2018] 归程
题目链接: UOJ LOJ 感觉 Kruskal 重构树比较简单,就不单独开学习笔记了. Statement 给定一个 \(n\) 点 \(m\) 边的无向连通图,用 \(l,a\) 描述一条边的长度 ...
- uniapp导入导出Excel
众所周知,uniapp作为跨端利器,有诸多限制,其中之一便是vue页面不支持传统网页的dom.bom.blob等对象. 所以,百度上那些所谓的导入导出excel的方法,大部分都用不了,比如xlsx那个 ...
- STL——容器(deque) deque 的大小
1. deque 的大小 deque.size(); //返回容器中元素的个数 1 #include <iostream> 2 #include <dequ ...
- The Linux Scheduler: a Decade of Wasted Cores
The Linux Scheduler: a Decade of Wasted Cores 这是一篇介绍Linux调度问题的文章,源自这篇文章.文章中涉及到的一些问题可能已经得到解决,但可以学习一下本 ...
- EasyExcel导入
记录摸鱼的一天 技术栈:spring boot2.x+mybatis plus+easyExcel 2.2.6 生成简单的实体类等等等等 导入easyExcel的依赖 实体类 编写服务层 import ...
- 软件工程与UML的第一次课
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzzcxy/2018SE1 | | 这个作业要求在哪里 | https://edu.cnblogs.com ...
- ATS push cache 测试
测试 ATS 注入缓存 参考了: http://serverfault.com/questions/471684/push-content-to-apache-traffic-servers-cach ...
- 网站开发学习Python实现-Django项目部署-同步之前写的博客(6.2.2)
@ 目录 1.说明 2.思路 3.代码 关于作者 1.说明 之前写的博客都在csdn和博客园中 要将博客同步到自己的博客网站中 因为都是使用markdown格式书写的,所以直接爬取上传就完事 2.思路 ...
- 程序综合设计实践 :QT实现计算器
程序综合设计实践 :用QT实现简易计算器及贷款计算 1,项目概述 该项目目标是设计开发一个支持连续计算的包括括号( ),求余%四则运算+ - * /的计算器 Calculator 以及贷款计算功能 M ...
- SpringBoot事件监听机制及观察者模式/发布订阅模式
目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...