1 Star 0 Fork 38

hua-demo / java面试迷你版

forked from papi林 / java面试迷你版 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
类加载过程.md 3.68 KB
一键复制 编辑 原始数据 按行查看 历史
papi林 提交于 2021-07-19 01:33 . update pages/类加载过程.md.

类加载过程

可能发生类加载的情况:new、反射、new子类的时候父类还没加载、调用mian方法初始化该类。

类加载过程: 加载(文件二进制流到可使用的数据结构)->链接->初始化(init方法)。连接过程分为:验证(检查class文件的正确性、字节码、符号引用、元数据和文件格式的验证)->准备(初始化零值)->解析(符号引用【因为一开始不知道引用的是什么,所以会使用特定符号来表示】转直接引用)

  1. 加载 :1.通过类名获取定义此类的二进制文字流(还可自定义类加载器)。2.字节流代表的静态储存结构转换为方法区的运行时数据结构。3.在内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口。

*数组类型不通过类加载器创建,它由Java虚拟机直接创建。

*类加载器:JVM内置了三个重要的ClassLoader,除了BootstrapClassLoader,其他都是由Java实现自java.lang.classloader。

  • BootstrapClassLoader(启动类加载器): 最顶层的加载类,由C++实现,负责加载%JAVA_HOME%/lib目录下的jar包和类或者被-Xbootclasspath参数指定的路径的所有类。
  • ExtensionClassLoader(拓展类加载器): 主要负责加载目录%JAVA_HOME%/lib/ext目录下的jar包和类,或被java.ext.dirs系统变量所指定的路径下的jar包。
  • AppClassLoader(应用程序类加载器): 面向我们用户的加载器,负责加载当前应用classpath下所有的jar包和类。

*双亲委派模型(并非父母两个,而是指父母这一辈的): 每一个类都有一个对应它的类加载器,系统中的ClassLoader在协同工作的时候会默认使用双亲委派模型,即在类加载的时候,系统会首先判断当前类是否被加载过,已经被加载过类会直接返回,否则才会被尝试加载,加载的时候,首先会把该请求委派该父类加载器的loadClass()处理,因此所有的请求最终都应该传到最顶层的启动类加载器bootstrapClassLoader中。当父类加载器无法处理时,才由自己来处理,当父类加载器为null时,会启动类加载器BootstrapClassLoader作为父类加载器。这里的父子是按优先级定的,不是继承关系。

好处:保证Java程序的稳定运行,可以避免类的重复加载(JVM区分不同类的方式不仅仅根据类名,系统的类文件被不同的类加载器加载产生的是两个不同的类),保证了Java的核心API不被篡改,如果没有使用双亲委派模型,而是每个类加载器都加载自己的话就会出现一些问题,比较我们编写一个称为java.lang.Object类的话,那么程序运行的时候,系统就会出现不同的Object类。反正意思就是向上寻找是否已经加载过了。

bootstrapClassLoader必用因为它在虚拟机实现,其他不想用的话自己定义一个类加载器,重载loadClass()即可,就是继承ClassLoader。

隐式加载指的是程序在使用new等方式创建对象时,会隐式地调用类的加载器把对应的类加载到JVM中。显式加载指的是通过直接调用class.forName()方法把所需的类加载到JVM中。CLASS文件

.class文件包含以下:

image-20200309174450475 https://img2020.cnblogs.com/blog/932508/202107/932508-20210719085433990-1080358224.png

  • 魔数:确定这个class文件是否能被虚拟机接收。
  • class文件版本: class文件的版本号,保证编译正常执行。
  • ...
Java
1
https://gitee.com/hua-demo/javaLearn.git
git@gitee.com:hua-demo/javaLearn.git
hua-demo
javaLearn
java面试迷你版
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891