静态代码块:用staitc声明,jvm加载类时执行,仅执行一次
构造代码块:类中直接用{}定义,每一次创建对象时执行。
执行顺序优先级:(静态块| 静态变量) , main(), (构造块|成员变量) , 构造方法。
括号内的内容根据声明的先后顺序进行执行。

构造函数

public HelloA(){//构造函数}

关于构造函数,要注意:

  • 执行HelloA helloA = new HelloA():时,仅有等号左边不执行构造函数,只有显式调用new HelloA();时才会执行构造方法。

构造代码块

{                //构造代码块
}

关于构造代码块,以下几点要注意:

构造代码块的作用是给对象进行初始化。

  • 对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
  • 构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

静态代码块

static {//静态代码块
}

关于静态代码块,要注意的是:

  • 静态的内容是属于类的,从Java内存模型的角度来看静态的内容是存储在方法区的静态存储区中的,所以在静态代码块中声明的变量或对象的句柄都不再存储在栈中,而是存在于方法区中。(因为类加载总要在具体的内存分配之前,所以这也解释了为什么静态的内容总是最先执行)
  • 静态代码块随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
  • 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
  • 一个类中可以有多个静态代码块,且按照声明先后顺序执行。

第一次总结

Java类的初始化顺序遵循三个原则:

  1. 静态内容总是优于非静态的,静态呢绒从属于类,不属于某个具体的对象。正因为如此,静态内容的逻辑存储位置是在方法区中的静态存储区(方法区是多个线程共享的区域)中。故在静态变量在类装载的时候便已经进行了初始化,且只进行一次初始化(因为类只需要被ClassLoader装载一次至方法区中)
  2. 非静态的内容(构造代码块、成员变量、构造方法)属于某一个具体的对象,每个对象维护属于自己的那一块内存区域,所以他们只有在显式进行new对象的操作的时候才会执行。上面说了构造代码块的作用就是为了给成员变量进行初始化操作,他们之间的优先级是并列的,根据声明的顺序进行赋值操作。最后再执行构造方法。

注意:赋值操作是根据声明的先后顺序执行,但是变量的句柄是已经存在了的,看下面的例子:

思考一下段代码存在问题吗? 一点毛病也没有,编译器么有报错。我们不妨暂停思考一下运行结果。

这是我们的运行结果:
第一次跑出来的a是0,也就是句柄早已存在,并且被Jvm默认初始化为了0,然后构造代码块对a进行了初始化赋值操作。(使用this调用的原因是成员变量属于具体对象,需要this进行调用)

上面讨论的都是不存在继承关系的初始化顺序。
存在继承关系时,依旧遵循上面两条,且要增加一条,先初始化父类,后初始化子类。依然是静态优先,构造最后

一个很乱但是看懂了就很牛批的例子:

public class Employee {private String name = "lisi";{System.out.println("初始化1");name = "wangwu";age = 20;}private int age = 30;static {System.out.println("静态初始化1");System.out.println("id0:" + Employee.id);Employee.id = 40;System.out.println("id1:" + Employee.id);System.out.println("liuliu开始");Employee employee = new Employee("liuliu", 50);System.out.println(employee);System.out.println("liuliu id:" + employee.getId());System.out.println("liuliu结束");}private static int id = 30;{System.out.println("初始化2");name = "zhaosi";age = 40;}static {System.out.println("id2:" + Employee.id);System.out.println("静态初始化2");id = 80;System.out.println("id3:" + Employee.id);}public static int getId() {return id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Employee(String name, int age) {super();System.out.println("有參構造器");this.name = name;this.age = age;}public Employee() {super();System.out.println("無參構造器");}@Overridepublic String toString() {return "Employee [name=" + name + ", age=" + age + "]";}}
public class TestDefault {public static void main(String[] args) {System.out.println("tom开始");Employee tom = new Employee("tom", 20);System.out.println(tom);System.out.println(tom.getId());System.out.println("tom结束");System.out.println("jouty开始");Employee jouty = new Employee("jouty", 19);System.out.println(jouty);System.out.println(jouty.getId());System.out.println("jouty结束");System.out.println("jerry开始");Employee jerry = new Employee("jerry", 19);System.out.println(jerry);System.out.println(jerry.getId());System.out.println("jerry结束");}
}

我们的运行结果:

各位看官可以根据上面的分析自己分析一下子。

对Java类初始化顺序的一些理解相关推荐

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

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

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

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

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

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

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

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

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

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

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

    前言:最近写代码的时候经常见到见到static代码块,不由对static的执行时间产生了兴趣,进而对类初始化顺序产生了兴趣. 类从编译到执行的过程: 在使用ClassLoader将字节码转换为JVM中 ...

  7. 一文详解Java类初始化顺序

    目录 一.普通类 二.包含继承关系 三.包含接口.抽象类关系 本文将介绍三种情形下的类初始化顺序. 一.普通类 Java类:Animal.java package ztt.继承接口多态.执行顺序测试; ...

  8. java类初始化顺序_《To Be a Better Javaer》-- Java 基础篇 vol.2:面向对象

    Java是面向对象的高级编程语言,面向对象的特征如下: 面向对象具有抽象.封装.继承.多态等特性: 面向对象可以将复杂的业务逻辑简单化,增强代码复用性: 面向对象是一种常见的思想,比较符合人们的思考习 ...

  9. JAVA类初始化顺序总结

    类的初始化 初始化顺序 首先来看下,当一个类从main入口方法,对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序: public class ClassLoadTest {priv ...

最新文章

  1. 笔记 | PyTorch安装及入门教程
  2. 再学 GDI+[56]: 路径 - Warp
  3. Python中sklearn中HistGradientBoostingRegressor回归器配置单调约束参数monotonic_cst提高回归模型的抗噪声以及局部扰动的能力
  4. 【Android】Source Insight 基本用法 ( 导入 Android 源码 | 设置字体 | 显示行号 | 搜索功能 | 快捷键设置 )
  5. php表单数量,php – 解析具有未知数量字段的表单
  6. 笔记本蓝牙显示输入码无效_小白笔记本连接蓝牙设备进阶篇
  7. web服务之Tomcat
  8. 学长毕业日记 :本科毕业论文写成博士论文的神操作20170412
  9. 如何让IDEA启动多个SpringBoot实例
  10. mapstruct详解
  11. 计算机科学与技术博士论文,计算机科学与技术系博士学位论文答辩.PDF
  12. Java中array、List、Set互相转换
  13. 【转】Scala: Example use for early definition / early initializer / pre-initialized fields
  14. repo打了 tag之后如何提交tag_技术开发者应该如何构建小团队的微服务方案?
  15. 2021年Java开发者应该学习的技术
  16. 操作系统实验一:并发程序设计
  17. 为什么Zappos花钱让新员工走人?
  18. 在托管 Windows 服务中承载 WCF 服务
  19. 《产品经理面试攻略》PART 2:简历
  20. 科技护肤品,买还是不买

热门文章

  1. 使用Python+Flask+OpenCV构建一个相机应用程序
  2. 短视频变现难,奖励看广告的用户会不会是一个好办法?
  3. 网易云课堂数据分析师教程分享
  4. style-resources-loader
  5. 4g模块注册上网 移远_【技术分享】Openwrt实现4G模块上网功能
  6. Defects4J查看错误源码
  7. 【Unity】Unity Shader学习笔记(二)渲染管线
  8. qt creator源码全方面分析(2-6)
  9. 解决Windows不能关机问题
  10. 如何开放服务器端口?