您的位置 首页 java

面试时又被java类加载的过程难倒了?一篇搞定

Java类加载的过程

每一个java语言的使用者一定听过这句著名的话:一次编译,处处运行。当然了作为java的开发者,现实中也有可能是一次编译,处处debug。不管怎么说,java虚拟机和类加载的过程都是java语言重要的一个特性,也是面试java开发者的常用问题,下面就通过这篇文章快速掌握中间的要点吧。

  1. 总体过程

面试时又被java类加载的过程难倒了?一篇搞定

这是一个简单的字节码编译和运行的过程。Java源码通过编译之后,变成了JVM(java虚拟机)可以直接运行的字节码文件

了解了 Java 字节码后,我们来聊聊 Java 的类加载过程。

Java 的类加载过程可以分为 5 个阶段:载入、验证、准备、解析和初始化。这 5 个阶段一般是顺序发生的,但在动态绑定的情况下,解析阶段发生在初始化阶段之后。下面这幅图就是一个完整的过程。接下来就具体来讲讲每个过程的细节

面试时又被java类加载的过程难倒了?一篇搞定

  1. 五个步骤的细节
  2. 加载: 用一句话来说就是:把代码数据加载到内存中。

这个二进制字节流的来源没有被限定,可以从zip包或者其他文件中读取,从网络中获得,运行中生成等。

然后,将这个字节流所代表的静态储存结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。

这里稍微理解一下对象和类的概念,对象是实例化的类。类的信息是存储在方法区中的,对象是存储在Java堆中的。类是对象的模板,对象是类的实例。

类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。

  1. 验证阶段

一句话:验证阶段就是验证该类是否符合Java虚拟机对于类的标准

验证阶段是Java非常重要的一个阶段,它会直接地保证应用是否会被恶意入侵的一道重要的防线,越是严谨的验证机制越安全。

具体而言该过程包括了以下部分:

文件格式验证,元数据验证,字节码验证,符号引用验证。

保障了自身的安全

  1. 准备阶段

一句话:为静态变量分配内存

该过程为程序中的静态变量分配内存并赋予默认值。例如 (如0、0L、null、false等)

而对于一个final类型的静态变量,如果该变量的值在编译时就可以确定下来,那么这个变量相当于宏变量。Java编译器会在编译时直接把这个变量出现的地方替换成它的值,因此即使程序使用该静态变量,也不会导致该类的初始化。

区别就在于final是在加载时直接给值,static这是一开始给默认值。

  1. 解析阶段

一句话:该阶段就是将常量池中的符号引用替换成直接其在内存中的直接引用。

首先解释一下涉及到的名词:

符号引用:符号引用是以一组符号来描述所引用的目标。

与符合引用相对的是直接引用:直接引用和虚拟机的布局是相关的,不同的虚拟机对于相同的符号引用所翻译出来的直接引用一般是不同的。如果有了直接引用,那么直接引用的目标一定被加载到了内存中。

直接引用可以是: 指向目标的指针,相对偏移量等。

解析阶段JVM 针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符这 7 类引用进行解析。

  1. 初始化阶段

一句话:初始化是为类的静态变量赋予正确的初始值

准备阶段和初始化阶段看似有点矛盾,其实是不矛盾的。

如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的。

所以,此时a等于int类型的默认初始值0,即a=0,然后到解析(后面再说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。

初始化阶段,才真正开始执行类中的Java程序代码。即初始化阶段是执行类构造器clinit方法的过程。

当以上的过程完成 之后,JVM 便开始从入口方法开始执行用户的程序代码了。类的加载过程就完成了。

文章来源:智云一二三科技

文章标题:面试时又被java类加载的过程难倒了?一篇搞定

文章地址:https://www.zhihuclub.com/175111.shtml

关于作者: 智云科技

热门文章

网站地图