首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【Java 虚拟机原理】Java 类中的类加载初始化细节 ( 只使用类中的常量加载类不会执行到 ‘初始化‘ 阶段 )

静态变量 的 指定赋值 , 是在 初始化 阶段 完成的 ; 类 在 " 初始化 " 阶段 , 调用 静态代码块 ; 二、常量加载示例 ---- 类加载 , 如果只用到了类中的常量 , 则只进行 "..." 阶段才执行 静态代码块 // 如果只是进行了 " 连接 " , 没有进行 初始化 , 则不会调用该代码块 System.out.println("Student..." 初始化 " 阶段 ; 因此这里不会调用 静态代码块 中的代码 ; Constant pool: #10 = Integer 18 三、数组加载示例 ---- 对数组进行创建操作..., 如创建了一个对象数组 , 此时不会加载该对象对应的类 , 只会为其在内存分配空间 ; 创建数组 , 触发的是 Student[] 数组类型的 类加载初始化 , 但是不会触发 Student 类的初始化操作...; 如果调用数组中的元素 , 就需要初始化 Student 类 ; Student 类 : public class Student { // 常量 public static final

3.6K20

【原创】JVM 的类加载机制?盘它!

根据这个流程,初始化触发类加载的第一个阶段---加载阶段肯定已经完成了,那我们可以这样推论,类初始化触发时机定会触发整个类加载过程。...初始化子类的时候,会触发父类的初始化。 作为程序入口直接运行时(也就是直接调用 main 方法) 除了以上四种情况,其他使用类的方式叫做被动引用,而被动引用不会触发类的初始化。...注意以下几种情况不会执行类初始化: 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。 定义对象数组,不会触发该类的初始化。...常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。 通过类名获取 Class 对象,不会触发类的初始化。...通过 Classs.forName 加载执行类,如果指定参数 initialize 为 false ,也不会触发初始化,其他这个参数是告诉虚拟机,是否要对类进行初始化

75220
您找到你想要的搜索结果了吗?
是的
没有找到

你真的懂「类的加载机制」吗?

被动引用 一个类如果是被动引用的话,该类不会触发初始化过程 1)通过子类引用父类的静态字段,不会导致子类初始化。...对于静态字段,只有直接定义该字段的类才会被初始化,因此当我们通过子类来引用父类中定义的静态字段,只会触发父类的初始化,而不会触发子类的初始化。 2)通过数组定义来引用类,不会触发此类的初始化。...3)常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。...2)将这个字节流所代表的静态存储结构转化为方法的运行时数据结构。 3)在java堆中生成一个代表这个类的java.lang.Class对象,作为方法这些数据的访问入口。...经过该阶段的验证后,字节流才会进入内存的方法中进行存储,后面的三个验证都是基于方法存储结构进行的。

53430

JVM解读-类加载机制

被动引用 一个类如果是被动引用的话,该类不会触发初始化过程 1)通过子类引用父类的静态字段,不会导致子类初始化。...对于静态字段,只有直接定义该字段的类才会被初始化,因此当我们通过子类来引用父类中定义的静态字段,只会触发父类的初始化,而不会触发子类的初始化。 2)通过数组定义来引用类,不会触发此类的初始化。...3)常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。...2)将这个字节流所代表的静态存储结构转化为方法的运行时数据结构。 3)在java堆中生成一个代表这个类的java.lang.Class对象,作为方法这些数据的访问入口。...经过该阶段的验证后,字节流才会进入内存的方法中进行存储,后面的三个验证都是基于方法存储结构进行的。

44030

Java魔法堂:类加载机制入了个门

准备(Preparation)     在方法为类变量分配内存空间,并初始化为0。示例如下: // 经过准备阶段后,value类变量将存储在方法中,值为0。123的赋值操作将在初始化阶段进行。...遇到new, getstatic, putstatic或invokestatic这4条字节码指令,若类没有进行过初始化,则需要先触发初始化。...使用`java.lang.reflect`包中的方法操作类,若类没有进行过初始化,则需要先触发初始化。   3. 当初始化一个类,若其父类还没初始化则会先初始化父类。   4....除了上述5种情况外,其他引用类的方式是不会触发初始化的,并称为被动引用。下列示例则为被动引用   1. 通过子类访问父类静态字段不会导致子类初始化,仅仅会导致父类初始化。   2....类A访问类B的静态常量不会导致类B的初始化。因为在编译阶段会将类使用到的常量直接存储到自身常量池的引用中,因此实际上运行时类A访问的是自身的常量与类B无关系。

92170

JVM第六卷---类加载机制

加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机设定的格式存储在方法之中了,方法中的数据存储格式完全由虚拟机自行定义。...子类初始化,如果父类还没初始化,会引发 子类访问父类的静态变量,只会触发父类的初始化 Class.forName new 会导致初始化 不会导致类初始化的情况 访问类的 static final...静态常量(基本类型和字符串)不会触发初始化 类对象.class 不会触发初始化 创建该类的数组不会触发初始化 类加载器的 loadClass 方法 Class.forName 的参数 2 为...静态常量(基本类型和字符串)不会触发初始化 System.out.println(B.b); // 2....创建该类的数组不会触发初始化 System.out.println(new B[0]); // 4.

42610

深入理解Java虚拟机05–虚拟机类加载机制「建议收藏」

二.加载过程 1、 加载(loading) 三件大事 1、通过类的全限定名来定义这个类的二进制流 2、将字节流代表的静态存储结构变成方法的运行时数据结构 3、在方法生成一个java.lang.Class...验证 确保Class文件的字节流中包含的信息符合当前虚拟机的要求,避免导致系统奔溃 验证类型 文件格式验证:保证输入的字节流能够正确的解析并存储于方法之内,格式上符合Java类型信息; 元数据验证...)这4个字节码指令 java.lang.reflect包的方法反射调用,类若没有初始化必须先进行初始化 初始化一个类,父类没有初始化,必须先初始化父类(但是接口不用,只有用到父接口,才会初始化) 虚拟机指定了...被动引用 子类引用父类的静态字段,只初始化父类,而不会触发初始化子类 通过数组定义来引用类,不会触发此类的初始化 常量在编译阶段会存入到调用类的常量池中,本质上没有直接应用调用到定义了常量的类,因此定义了常量的这个类不会触发初始化...如果,我们的操作不是上述的主动引用,其结果是没有触发本Class的初始化,而是间接的触发了别的Class进行初始化工作。我们称这个为被动引用。

25020

简述JVM基础(五):虚拟机类加载机制

1、 加载(loading) 三件大事 1、通过类的全限定名来定义这个类的二进制流 2、将字节流代表的静态存储结构变成方法的运行时数据结构 3、在方法生成一个java.lang.Class对象,作为方法数据的访问入口...但是数组的元素还是需要类加载器创建的; 2、 连接 (1)、 验证 确保Class文件的字节流中包含的信息符合当前虚拟机的要求,避免导致系统奔溃 验证类型 文件格式验证:保证输入的字节流能够正确的解析并存储于方法之内...)这4个字节码指令 java.lang.reflect包的方法反射调用,类若没有初始化必须先进行初始化 初始化一个类,父类没有初始化,必须先初始化父类(但是接口不用,只有用到父接口,才会初始化) 虚拟机指定了...被动引用 子类引用父类的静态字段,只初始化父类,而不会触发初始化子类 通过数组定义来引用类,不会触发此类的初始化 常量在编译阶段会存入到调用类的常量池中,本质上没有直接应用调用到定义了常量的类,因此定义了常量的这个类不会触发初始化...如果,我们的操作不是上述的主动引用,其结果是没有触发本Class的初始化,而是间接的触发了别的Class进行初始化工作。我们称这个为被动引用。

49510

Java常见面试题及答案 11-20(JVM)

如果该对象有必要执行finalize()方法,那么这个对象将会放在一个称为F-Queue的对队列中,虚拟机会触发一个Finalize()线程去执行,此线程是低优先级的,并且虚拟机不会承诺一直等待它运行完...在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。...这种方法很简单,但是会有两个主要问题:1.效率不高,标记和清除的效率都很低;2.会产生大量不连续的内存碎片,导致以后程序在分配较大的对象,由于没有充足的连续内存而提前触发一次GC动作。...每次都会优先使用Eden,若Eden满,就将对象复制到第二块内存上,然后清除Eden,如果此时存活的对象太多,以至于Survivor不够,会将这些对象通过分配担保机制复制到老年代中。...GC 发生在老年代,一般情况下,触发老年代GC的时候不会触发Minor GC,但是通过配置,可以在Full GC之前进行一次Minor GC这样可以加快老年代的回收速度。

1.3K90

java常见面试题及答案 11-20(JVM)

如果该对象有必要执行finalize()方法,那么这个对象将会放在一个称为F-Queue的对队列中,虚拟机会触发一个Finalize()线程去执行,此线程是低优先级的,并且虚拟机不会承诺一直等待它运行完...在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。...这种方法很简单,但是会有两个主要问题:1.效率不高,标记和清除的效率都很低;2.会产生大量不连续的内存碎片,导致以后程序在分配较大的对象,由于没有充足的连续内存而提前触发一次GC动作。...准备 准备阶段是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法中进行分配。...GC 发生在老年代,一般情况下,触发老年代GC的时候不会触发Minor GC,但是通过配置,可以在Full GC之前进行一次Minor GC这样可以加快老年代的回收速度。

19710

《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(上)

初始化一个类的时候,发现其父类还没有进行过初始化:需要先触发其父类的初始化。 虚拟机启动,用户指定一个要执行的主类(包含main()方法的那个类):虚拟机会先初始化包含main()方法的那个类。...除此之外的所有引用类的方式都不会触发初始化,称为被动引用。...对于被动引用,例如: 通过子类访问父类的静态字段,不会触发子类的初始化,只有直接定义这个字段的类才会被初始化 通过数组定义来引用类,不会触发此类的初始化:但是会触发另一个类的初始化,比如com.test.User...常量在编译阶段会存入调用类的常量池,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化:如果一个类A引用了另一个类B的常量,那么经过编译阶段的常量传播优化,已经将此常量存储到了A类的常量池中...只有通过了这个验证,字节流才会即进入方法存储,所以后面的3个验证阶段都是基于方法存储结构进行的。 元数据验证:对字节码描述的信息进行语义分析,以保证其符合Java语言规范要求。

50120

jvm字节码和类加载机制

这 5 种场景称为对一个类进行主动引用(有且只有这五种才可以触发类的初始化),除此之外,其它所有引用类的方式都不会触发初始化,称为被动引用。...} } 对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化不会触发子类的初始化。.../** * 被动引用 Demo2: * 通过数组定义来引用类,不会触发此类的初始化。...static void main(String[] args) { SuperClass[] superClasses = new SuperClass[10]; } } new数组对象不会触发.../** * 被动引用 Demo3: * 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化

39110

Java虚拟机

主动引用( 必须初始化 的场景) 遇到new、getstatic、putstatic或invokestatic这四条字节码指令,如果类型没有进行过初始化,则需要先触发初始化阶段 使用java.lang.reflect...包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发初始化初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化 当虚拟机启动,用户需要指定一个要执行的主类...被动引用 通过子类引用父类的静态字段,不会导致子类初始化 对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化不会触发子类的初始化。...通过数组定义来引用类,不会触发此类的初始化 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化 三、类加载的过程 加载、验证、准备、解析和初始化 5...这阶段的验证是 基于二进制字节流 进行的,只有通过了这个阶段的验证之后,这段字节流 才被允许进入Java虚拟机内存的方法 中进行存储,所以后面的三个验证阶段全部是 基于方法存储结构 上进行的,不会再直接读取

62420

Java虚拟机

主动引用( 必须初始化 的场景) 遇到new、getstatic、putstatic或invokestatic这四条字节码指令,如果类型没有进行过初始化,则需要先触发初始化阶段 使用java.lang.reflect...包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发初始化初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化 当虚拟机启动,用户需要指定一个要执行的主类...被动引用 通过子类引用父类的静态字段,不会导致子类初始化 对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化不会触发子类的初始化。...通过数组定义来引用类,不会触发此类的初始化 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化 三、类加载的过程 加载、验证、准备、解析和初始化 5...这阶段的验证是 基于二进制字节流 进行的,只有通过了这个阶段的验证之后,这段字节流 才被允许进入Java虚拟机内存的方法 中进行存储,所以后面的三个验证阶段全部是 基于方法存储结构 上进行的,不会再直接读取

70100

JVM面试题详解

在 JVM 中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足,才会触发执行,扫面那些没有被任何引用的对象, 并将它们添加到要回收的集合中,进行回收。...垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回(Full GC)。注:Java 8 中已经移除了永久代,新加了一个叫做元数据的 native 内存。...JVM 分为堆和栈,还有方法初始化的对象放在堆里面,引用放在栈里面, class 类信息常量池(static 常量和 static 变量)等放在方法new:方法:主要是存储类信息,常量池(static...在JVM 中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。...Gc/Major GC 发生在老年代,一般情况下,触发老年代 GC 的时候不会触发 Minor GC,但是通过配置,可以在 Full GC 之前进行一次 Minor

41141

Java虚拟机类加载机制浅谈

2) 使用reflect包对类进行放射调用的时候,如果类没有进行初始化,则先要初始化该类      3) 当初始化一个类的时候,如果其父类没有初始化过,则先要触发其父类初始化。      ...注意:通过子类引用父类静态字段,只会初始化父类不会初始化子类;通过数组定义来引用类,也不会触发该类的初始化;常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此也不会触发定义常量的类的初始化...元数据验证:基于方法存储结构验证,对字节码描述信息进行语义验证。      字节码验证:基于方法存储结构验证,进行数据流和控制流的验证。      ...符号引用验证:基于方法存储结构验证,发生在解析中,是否可以将符号引用成功解析为直接引用。...2)在加载类,每个类加载器会将加载任务上交给其父,如果其父找不到,再由自己去加载。

75860

类加载器解析(1)类生命周期

数组类的可见性和组件类型一致 转换 获取之后,二进制字节流将按照虚拟机所需格式存储在方法之中。...具体如何存储在JVM虚拟机规范中并没有指明 生成 在内存中生成一个代表这个类的java.lang.Class对象,作为方法这个类各个数据的访问入口 对于HotSpot的加载流程 这个加载的流程可以参考下图...这个验证也分为如下几步: - 文件格式检验:这阶段会验证很多,并且这个阶段是和加载重合的一个阶段,通过这个阶段的验证后,字节流会进入方法存储(JDK1.8以后是元数据),之后所有的验证都是基于方法去的数据结构进行...初始化 虚拟机规范规定,下列情况下必须触发该类的初始化: - JVM遇到需要引用类的指令:new, getstatic, putstatic和invokestatic遇到 new 、 getstatic...,则需要先触发初始化 以上行为成为对一个类进行主动引用,除此之外,所有应用类的方式都不会触发类的初始化过程,称为被动调用 初始化这个过程实际上就是执行类构造器()方法的过程,这个方法是: 在Java

36810

jvm系列之类加载机制

2.加载    加载是类加载机制的第一个阶段,在这个阶段,虚拟机做了三件事情: 通过类的全限定名来获取定义此类的二进制字节流; 将这个字节流所代表的静态存储结构转换为方法的运行时数据结构 在内存中生成一个代表这个类的...Class对象,作为方法这个类的各种数据的访问入口    加载阶段完成后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法之中,方法中的数据存储格式由虚拟机实现自行定义;然后在内存中实例化一个...,如果累没有进行初始化,则需要先触发初始化。...当虚拟机启动,用户需要指定一个要执行的主类,虚拟机会先初始化那个类。 以上五种情况称为对一个类进行主动引用;其他引用类的方式都不会触发初始化,称为被动引用。...111 显然,子类没有被初始化,这里SubClass.number为被动引用,不会对子类初始化

14710

类加载机制你真的了解吗?

加载阶段完成之后,虚拟机就会把外部的二进制字节流(不论从何处获取的)按照一定的数据格式存储在运行时数据中的方法。...类的初始化时机:只有对类主动使用的时候才会触发初始化,主动使用的场景如下: 使用new关键词创建对象,访问某个类的静态变量或给静态变量赋值,调用类的静态方法。...反射调用时,会触发类的初始化(如Class.forName()) 初始化一个类的时候,如其父类未初始化,则会先触发父类的初始化。 虚拟机启动,会先初始化主类(即包含main方法的类)。...另外,也有些场景并不会触发类的初始化: 通过子类调用父类的静态变量,只会触发父类的初始化,而不会触发子类的初始化(因为,对于静态变量,只有直接定义这个变量的类才会初始化)。...通过数组来创建对象不会触发此类的初始化。(如定义一个自定义的Person[] 数组,不会触发Person类的初始化) 通过调用静态常量(即static final修饰的变量),并不会触发此类的初始化

55021

JVM-类加载子系统

但是类的初始化阶段,规范中明确规定当某个类没有进行初始化,只有以下6中情况才会触发初始化过程。...遇到new,getStatic,putStatic,invokeStatic,这四条字节码指令的时候,如果改类型没有进行初始化,则会触发初始化。...当初始化某个类,发现其父类没有初始化的时候。 当虚拟机启动的时候,会触发其主方法所在的类进行初始化。...对于以上6中触发类的初始化条件,在JVM规范中有一个很强制的词,if and only if (有且只有)。这六种行为被称为对类进行主动引用,除此之外,其他引用类的方式均不会触发类的初始化。 二。...只有通过这个阶段的验证之后,这一段字节流才会进入虚拟机内存中进行存储,之后的过程都是基于方法中的存储结构进行的。不会直接读取字节流了。

39910
领券