java中类加载时机
java虚拟机规范虽然没有强制性约束在什么时候开始类加载过程,但是对于类的初始化,虚拟机规范则严格规定了有且只有四种情况必须立即对类进行初始化,遇到new、getStatic、putStatic或invokeStatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
生成这4条指令最常见的java代码场景是:
1)使用new关键字实例化对象
2)读取一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)
3)设置一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)
4)调用一个类的静态方法
验证:
1)当类被初始化时,其静态代码块会执行。
class ClassLoadTime{
static{
System.out.println("ClassLoadTime类初始化时就会被执行!");
}
public ClassLoadTime(){
System.out.println("ClassLoadTime构造函数!");
}
}
class ClassLoadDemo{
public static void main(String[] args){
ClassLoadTime clt = new ClassLoadTime();
}
}
输出结果:
ClassLoadTime类初始化时就会被执行!
ClassLoadTime构造函数!
2) 读取一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)
class ClassLoadTime{
static{
System.out.println("ClassLoadTime类初始化时就会被执行!");
}
public static int max = 200; (防止测试类和此类不在一个包,使用public修饰符)
public ClassLoadTime(){
System.out.println("ClassLoadTime构造函数!");
}
}
class ClassLoadDemo{
public static void main(String[] args){
int value = ClassLoadTime.max;
System.out.println(value);
}
}
输出:
ClassLoadTime类初始化时就会被执行!
200
3)设置一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)
class ClassLoadTime{
static{
System.out.println("ClassLoadTime类初始化时就会被执行!");
}
public static int max = 200; (防止测试类和此类不在一个包,使用public修饰符)
public ClassLoadTime(){
System.out.println("ClassLoadTime构造函数!");
}
}
class ClassLoadDemo{
public static void main(String[] args){
ClassLoadTime.max = 100;
}
}
输出:
ClassLoadTime类初始化时就会被执行!
4)调用一个类的静态方法
class ClassLoadTime{
static{
System.out.println("ClassLoadTime类初始化时就会被执行!");
}
public static int max = 200; (防止测试类和此类不在一个包,使用public修饰符)
public ClassLoadTime(){
System.out.println("ClassLoadTime构造函数!");
}
public static void method(){
System.out.println("静态方法的调用!");
}
}
class ClassLoadDemo{
public static void main(String[] args){
ClassLoadTime.method();
}
}
输出:
ClassLoadTime类初始化时就会被执行!
静态方法的调用!
被final修饰静态字段在操作使用时,不会使类进行初始化,因为在编译期已经将此常量放在常量池。
测试:
class ClassLoadTime{
static{
System.out.println("ClassLoadTime类初始化时就会被执行!");
}
public static final int MIN = 10; (防止测试类和此类不在一个包,使用public修饰符)
}
class ClassLoadDemo{
public static void main(String[] args){
System.out.println(ClassLoadTime.MIN);
}
}
输出:
10
子类调用或者设置父类的静态字段或者调用父类的静态方法时仅仅初始化父类,而不初始化子类。同样读取final修饰的常量不会进行类的初始化。
class Fu{
public static int value = 20;
static{
System.out.println("父类进行了类的初始化!");
}
}
class Zi{
static{
System.out.println("子类进行了类的初始化!");
}
}
class LoadDemo{
public static void main(String[] args){
System.out.println(Zi.value);
}
}
输出:
父类进行了类的初始化!
20
java类中各种成员的初始化时机,此处不一一测试:
类变量(静态变量)、实例变量(非静态变量)、静态代码块、非静态代码块 的初始化时机:
* 由 static 关键字修饰的(如:类变量[静态变量]、静态代码块)将在类被初始化创建实例对象之前被初始化,而且是按顺序从上到下依次被执行;
public static int value =34;
static{
System.out.println("静态代码块!");
}
public 类名(){
System.out.println("构造函数!");
}
一旦这样写,在类被初始化创建实例对象之前会先初始化静态字段value,然后执行静态代码块,当实例化对象时会执行构造方法中的代码
* 没有 static 关键字修饰的(如:实例变量[非静态变量]、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的
代码块优先执行到,其也是按顺序从上到下依次被执行。
public int value =34;
{
System.out.println("非静态代码块!");
}
public 类名(){
System.out.println("构造函数!");
}
在使用构造函数实例化一个对象时,会先初始化value,然后执行非静态代码块,最后执行构造方法里面的代码。
*在存在父类的时候,调用子类的构造时,会先调用父类的默认构造(空参构造),进行父类的初始化。
java中类加载时机的更多相关文章
- java 中类加载器
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式. java 中类加载器分为三个: BootstrapClassLoader 负责加载 ${ ...
- ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗
1.ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗? :当然是运行期间啊,我自己有个理解误区,改正后如下:编译期间编译器是不去加载类的,只负责编译而 ...
- java中类加载顺序(深入Java)
未涉及虚拟机 0.<init>与<clinit>的区别 1.类的加载过程 2.类的使用方式 3.类的加载来源 4.重载之泛型参数不同可以吗 5.参考 引子 记得上次中秋一哥们写 ...
- Java中类加载和反射技术实例
我们知道一个对象在运行时有两种类型,一个是编译类型,一个是运行时类型.在程序运行时,往往是需要发现类和对象的真实的信息的.那么如何获的这种信息呢? 其一,如果我们在编译和运行时都知道类型的具体信息,这 ...
- java中类加载的全过程及内存图分析
类加载机制: jvm把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成jvm可以直接使用的java类型的过程. (1)加载 将class文件字节码内容加载到内存中,并将这些静态数据转 ...
- Java中类加载的过程
类加载过程 这里的加载过程是严格按照加载开始顺序进行的,注意是加载开始而不是加载完成.也就是有可能会有两个或几个阶段是同时进行的. 比如下面提到的验证过程中的符号引用验证是在解析阶段开始之后进行. 加 ...
- Java中类加载过程和对象创建过程
类加载过程: 1, JVM会先去方法区中找有没有相应类的.class存在.如果有,就直接使用:如果没有,则把相关类的.class加载到方法区 2, 在.class加载到方法区时,会分为两部分加载:先加 ...
- java中初始化时机和顺序呢
class Pupil{ Pupil(int age){ System.out.println("Pupil:"+age); } } class Teacher{ Pupil p1 ...
- 从一道面试题来认识java类加载时机与过程
说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1 开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...
随机推荐
- 老毛桃制作装机版u盘
启动盘准备工作: ① 老毛桃官网首页下载老毛桃v9.3装机版u盘启动盘制作工具安装到电脑上: ② 准备一个容量大在4G以上并能够正常使用的u盘. 第一步 到老毛桃官网中下载老毛桃v9.3安装包到系统桌 ...
- HTML(六)--总结
1.行级元素/内联元素 inline 特点: 1)内容决定元素所占位置(所占大小),不独占一行 2)元素之间存在默认大小的间隙 3)不可以通过CSS改变宽高 span strong em a del ...
- day038 navicat pymysql
今日内容: 1.navicat 2.pymysql 1.navicat 需要掌握 #1. 测试+链接数据库 #2. 新建库 #3. 新建表,新增字段+类型+约束 #4. 设计表:外键 #5. 新建查询 ...
- java动手动脑3
2016-10-152016-10-15一.编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数. 生成50个1到10的随机整数. value=a+(int)(Math.Random() ...
- Android : App通过LocalSocket 与 HAL间通信
LocalSocket其通信方式与Socket差不多,只是LocalSocket没有跨越网络边界.对于*nix系统来说,“一切皆为文件”,Socket也不例外,Socket按照收发双方的媒介来说有三种 ...
- 深入理解java虚拟机---虚拟机工具jmap(十六)
原文: https://www.cnblogs.com/myna/p/7573843.html jmap JVM Memory Map命令用于生成heap dump文件,如果不使用这个命令,还可以使用 ...
- linux系统安装jdk详细配置
1.通过指令 whereis java 查看是否已经配置jdk 如果已经安装,通过指令 rm -rf <jdk路径> 删除 2.通过ssh工具将jdk-8u11-linux-x64.tar ...
- FPGA复位的可靠性(转)
FPGA复位的可靠性(同步复位和异步复位) reference:http://www.eetop.cn/blog/html/17/743817-24442.html 一.特点: 同步复位:顾名思义, ...
- 用户登陆代码py
实现用户输入用户名和密码,当用户名为 seven 且 密码为 123 时,显示登陆成功,否则登陆失败! 实现用户输入用户名和密码,当用户名为 seven 且 密码为 123 时,显示登陆成功,否则登陆 ...
- ubantu 常用命令
1.显示日期与时间的命令:date 2.显示日历的命令:cal 3.简单好用的计算器:bc 4.热键“命令补全或文件补齐”:Tab 5.热键“中断目前程序”:Ctrl+C 6.热键“键盘输入结束(En ...