前言:最近写代码的时候经常见到见到static代码块,不由对static的执行时间产生了兴趣,进而对类初始化顺序产生了兴趣.

类从编译到执行的过程:

在使用ClassLoader将字节码转换为JVM中的Class<Robot>对象时,要下图所示进行几个过程.

所以类的初始化就在第三步,总的来说遵守下面的规则:

1、 假如这个类还灭有被加载和连接,那就先加载和连接

2、 假如类中存在直接的父类,或者间接父类,并却该父类没有被初始化,则先初始化父类

3(核心)、 类初始化的顺序 :父类的静态成员变量赋值与静态代码块按顺序执行->子类的静态成员变量赋值与静态代码块按顺序执行->父类的非静态成员变量赋值与非静态代码块的执行->父类的构造函数->子类的非静态成员变量赋值与非静态代码块的执行,如果类没有new那么只会执行静态的赋值.

实例:

输出为(只执行了静态):

如果在main里面new了一个Test7()

输出为:

额外的知识:

1.类什么时候会被加载

类的加载是通过类加载器(Classloader)完成的,它既可以是饿汉式[eagerly load](只要有其它类引用了它就加载)加载类,也可以是懒加载[lazy load](等到类初始化发生的时候才加载),虚拟机规范则严格规定了有且只有四种情况必须立即对类进行初始化.

1)使用new关键字实例化对象

2)读取一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)

3)设置一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)

4)调用一个类的静态方法

2.类被加载后会放在哪里

没有new出来之前,加载的时候ClassLoader会在java堆中生成一个代表这个类的Class对象,作为访问方法区(元空间)中这些数据的入口。

3.static final修饰的类型

基本类型:用static final修饰的基本类型,编译器认为该变量是不会被修改的,所以在编译时就会在引用类中写死,以增加效率,所以编译后就变成了写死的值,而不是引用。

4.对象的内存分配问题

参考:https://blog.csdn.net/topdeveloperr/article/details/81194654

创建对象时,对象的成员变量先进行默认初始化,其中:

基本类型初始化为基本类型默认值,如: int 类型的默认值为0,boolean类型的默认值为false;
对象引用类型默认初始化为null,如: Object obj = new xxx();
引用变量的引用地址obj存放在栈(stack)内存中,对象的成员变量及值存放在堆内存中。

这里可以额外引申一点的就是关于线程安全的问题,在这里我们已经知道了,对象的成员变量会在堆中分配,但是局部变量(即方法体中的变量)不会。我们可以得到的的启示是:

局部变量肯定是线程安全的。每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,故不存在线程安全问题。在方法中声明的变量可以是基本类型的变量,也可以是引用类型的变量:
当声明是基本类型的变量的时,其变量名及值(变量名及值是两个概念)是放在方法栈中。

当声明的是引用变量时,所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在方法的栈中,该变量所指向的对象是放在堆类存中的。

而成员变量就要看它初始化的模式。若是单例模式, 实例变量为对象实例私有,在虚拟机的堆中分配,若在系统中只存在一个此对象的实例,在多线程环境下,被某个线程修改后,其他线程对修改均可见,故线程非安全;如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变量的修改将互不影响,故线程安全。
静态变量肯定不是线程安全的。静态变量在内存中的位置既不在堆中,也不在栈上,而是在方法区的运行时常量池中,而这个部分是所有线程共享的。
当创建一个对象的时候,堆里面只会存放这个对象的头信息(这里面会包含有指向这个对象对应的class以及methods的引用)以及它的字段。

Java类初始化顺序(变量赋值与静态代码块的执行时间)相关推荐

  1. Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序

    构造函数 public HelloA(){//构造函数} 关于构造函数,以下几点要注意: 1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象,构造函数时不会运行的. 2.构造函数的作用是 ...

  2. Java类初始化、变量初始化

    Java类初始化.变量初始化 摘自:https://blog.csdn.net/mocas_wang/article/details/109956014 基础知识 Java常量, final 修饰,值 ...

  3. 对Java类初始化顺序的一些理解

    静态代码块:用staitc声明,jvm加载类时执行,仅执行一次 构造代码块:类中直接用{}定义,每一次创建对象时执行. 执行顺序优先级:(静态块| 静态变量) , main(), (构造块|成员变量) ...

  4. 【知识总结】Java类初始化顺序说明

    微信公众号:努力编程的小猪 如有问题或建议,请公众号留言 Java类初始化顺序说明 一个类中包含如下几类东西,他们前后是有顺序关系的 静态属性:static 开头定义的属性 静态方法块: static ...

  5. java类初始化顺序_「漫画」Java中的父子类的执行顺序到底是怎么一回事?

    ----下课后---- 结论 类的加载顺序. (1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法) (2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 ) (3) ...

  6. (转)java类初始化顺序 - jackyrong的世界 - 博客园

    (转)java类初始化顺序 我们大家都知道,对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器.我们也可以通过 ...

  7. java类初始化顺序_Java 类的初始化顺序

    静态代码块:用staitc声明,jvm加载类时执行,仅执行一次 构造代码块:类中直接用{}定义,每一次创建对象时执行 执行顺序优先级:静态块,main(),构造块,构造方法 1. 构造函数 publi ...

  8. 面试题:Java类初始化顺序

    1. 问题来源 你遇到过哪些质量很高的 Java 面试? - ZO01的回答 - 知乎 https://www.zhihu.com/question/60949531/answer/579002882 ...

  9. JAVA之旅(五)——this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块...

    JAVA之旅(五)--this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块 周末收获颇多,继续学习 一.this关键字 用于区分局部变量和成员变量同名的情况 ...

最新文章

  1. hdu4920 矩阵乘法%3
  2. spring-security-oauth2注解详解
  3. Android Camera 系统架构源码分析
  4. Android 过滤无效录音数据,android – MediaRecorder类记录音频的问题 – prepare()给出异常 – 权限被拒绝...
  5. 《对不队》团队项目用户验收评审
  6. c语言 nan 常量_NaN32常量(Julia)
  7. vue+element使用动态加载路由方式实现三级菜单页面显示问题
  8. 史上最全的Android基础教程+入门实战训练+处理技巧(建议收藏)|寻找C站宝藏
  9. 我需要HCNE模拟考试系统
  10. winsxs文件夹可以删除吗?具体清理操作如下
  11. Python之You-Get库学习
  12. python识别图片轮廓_教你用Python+opencv来识别物体的轮廓并标识显示
  13. linux挖矿的清理工具,Linux挖矿病毒的清除与分析
  14. 理解物理 CPU 与逻辑 CPU
  15. 大学计算机课程学情分析,大学计算机基础课程教学内容调查分析.doc
  16. Gem5模拟器,详解官网教程Debugging gem5(四)
  17. 走进前端 VScode插件安装 Gitee提交
  18. 校验手机号正则,支持166及199等手机号
  19. 科普|未来 3~5 年内,哪个方向的机器学习人才最紧缺?
  20. 银河麒麟操作系统(kylin os)学习

热门文章

  1. linux 删除模块命令,Linux系统中的Modprobe命令:添加和删除Linux内核模块的方法
  2. The 10 Best Neighborhoods in Seattle
  3. ISO七层模型和TCP/IP四层模型
  4. oracle job interval(关于时间误差)
  5. oracle时间平均,Oracle SQL的平均时间
  6. Android MultiDex 源码分析
  7. JDK1.6“新“特性Instrumentation之JavaAgent
  8. 3GPP TS 23501-g51 中英文对照 | 5.3.1 General
  9. python知到答案_Python语言应用_知到网课答案
  10. sourcetree远端 红色叹号