很有意思的一篇文章

1.没有继承

静态变量->静态初始化块->变量->变量初始化块->构造方法

2.有继承的情况

父类静态变量->父类静态初始化块->子类静态变量->子类静态变量初始化块->父类变量初始化->父类变量初始化块->父类构造方法->子类变量初始化->子类变量初始化块->子类构造方法

--------------------------------------------------我是copy分割线---------------------------------------------------------

大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我们对于继承情况下类的初始化顺序的了解。

我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:

Java代码

public class InitialOrderTest {

// 静态变量

public static String staticField = "静态变量";

// 变量

public String field = "变量";

// 静态初始化块

static {

System.out.println(staticField);

System.out.println("静态初始化块");

}

// 初始化块

{

System.out.println(field);

System.out.println("初始化块");

}

// 构造器

public InitialOrderTest() {

System.out.println("构造器");

}

public static void main(String[] args) {

new InitialOrderTest();

}

}

运行以上代码,我们会得到如下的输出结果:

静态变量

静态初始化块

变量

初始化块

构造器

这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:

Java代码

class Parent {

// 静态变量

public static String p_StaticField = "父类--静态变量";

// 变量

public String p_Field = "父类--变量";

// 静态初始化块

static {

System.out.println(p_StaticField);

System.out.println("父类--静态初始化块");

}

// 初始化块

{

System.out.println(p_Field);

System.out.println("父类--初始化块");

}

// 构造器

public Parent() {

System.out.println("父类--构造器");

}

}

public class SubClass extends Parent {

// 静态变量

public static String s_StaticField = "子类--静态变量";

// 变量

public String s_Field = "子类--变量";

// 静态初始化块

static {

System.out.println(s_StaticField);

System.out.println("子类--静态初始化块");

}

// 初始化块

{

System.out.println(s_Field);

System.out.println("子类--初始化块");

}

// 构造器

public SubClass() {

System.out.println("子类--构造器");

}

// 程序入口

public static void main(String[] args) {

new SubClass();

}

}

运行一下上面的代码,结果马上呈现在我们的眼前:

父类--静态变量

父类--静态初始化块

子类--静态变量

子类--静态初始化块

父类--变量

父类--初始化块

父类--构造器

子类--变量

子类--初始化块

子类--构造器

现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。

同样,我们还是写一个类来进行测试:

Java代码

public class TestOrder {

// 静态变量

public static TestA a = new TestA();

// 静态初始化块

static {

System.out.println("静态初始化块");

}

// 静态变量

public static TestB b = new TestB();

public static void main(String[] args) {

new TestOrder();

}

}

class TestA {

public TestA() {

System.out.println("Test--A");

}

}

class TestB {

public TestB() {

System.out.println("Test--B");

}

}

运行上面的代码,会得到如下的结果:

Test--A

静态初始化块

Test--B

大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。

了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。

静态块与静态成员的初始化工作与实例化过程无关,实例化必须先执行静态块和静态成员,但并不代表实例化一定会执行静态块和静态成员。只有当实例化的对应的类为加载入虚拟机的时候,才会进行这种操作。有些时候执行静态块或者初始化静态成员不一定就是实例化该类对象才会进行的,例如调研该类的某静态成员或者静态方法,又例如该类的子类被实例化或者调用了静态成员或静态方法等。

还有实例化的实际顺序其实是(省略类初始化过程)

1、进入当前类构造方法。

2、进入父类构造方法递归直到java.lang.Object类构造方法。

3、执行java.lang.Object类构造方法,顺序依次为成员变量初始与初始化块(安装上下文顺序),对应调用的构造方法体。

4、执行java.lang.Object类的直接子类的构造函数,这个过程递归到当前类。

5、当前类执行顺序与前面java.lang.Object类相同。

构造方法的本质其实就是一个普通的无返回参数的名字叫做的方法,不过虚拟机调用这个方法的指令与其它方法不同而已,它的调用指令与调用private方法的指令相同。

在虚拟机中存在三种方法的调用指令,这三种调用指令在效率上不同。

接口方法的指令调用,这种调用速度最慢。

普通类方法的调用指令,这种调用速度中等。

构造方法与私有方法调用指令,这种调用速度最快。

java类的静态成员初始化_Java类的初始化顺序 (静态变量、静态初始化块、变量、初始......相关推荐

  1. java 接口初始化_Java类的初始化 | 学步园

    类的初始化时机1.创建类的实例 2.访问类或接口的静态变量(static final常量除外,static final变量可以)3.调用类的静态方法 4.反射(Class.forName(packag ...

  2. java的连接 初始化_java类从加载、连接到初始化过程详解

    Java代码在编译后会转化成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化成汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. 类加载 ...

  3. java对类对象初始化_Java类和对象初始化

    Java类和对象初始化Tag内容描述: 1.解析 Java 类和对象的初始化过程 由一个单态模式引出的问题谈起 北京高伟达西南分软 Java EE 软件工程师 三年 Java EE 项目经验 行业方向 ...

  4. java 接口初始化_Java类和接口的初始化

    类的初始化由执行类中静态代码块的初始化和类中声明的静态域的初始化两部分组成 接口的初始化由接口中声明的域(常量)的初始化组成 初始化的时机 类或接口T在以下任意情况发生之前会立即进行初始化:T是一个类 ...

  5. JAVA类和对象访问_Java类和对象

    一.类 类是封装对象的属性和行为的载体,在Java语言中对象的属性以成员变量的形式存在,而对象的方法以成员方法的形式存在. 1. 类的构造方法 构造方法是一个与类同名的方法,对象的创建就是通过构造方法 ...

  6. java类与对象作用_Java类与对象

    ●类和对象的关系: 一:类是对同一类事物(对象)的抽象,对象实际存在的该类的各种实体. 二:面向对编程的核心:找合适的对象来做合适的事. 三:Java中找到对象: 1):sun自己定义好的类,必须知道 ...

  7. java类验证和装载顺序_Java类的加载机制和双亲委派模型

    Java类的加载机制和双亲委派模型 1类的加载机制 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading).验证(Verification).准备(Prepar ...

  8. java中static的用法_Java类中static的用法

    关于Java中static的使用有以下四种情况: 1.静态成员变量        被static修饰的成员变量,叫静态成员变量或类变量:没有被static修饰的变量,叫实例变量. 两者的区别是: 静态 ...

  9. java类对象实验问题_Java类与对象实验答案

    Java类与对象实验答案Tag内容描述: 1.Java实验报告 计科.信工版2013-2014-2 实验报告 一.实验项目:类与对象 二.实验目的: 1. 学会使用类来封装对象的属性和功能 2. 掌握 ...

最新文章

  1. Oracle 密码文件
  2. IT行业: 嵌入式工程师的进阶之路
  3. SVD java 算法实现
  4. Codeforces 264B Good Sequences ★ (分解素因子+DP)
  5. android webview 长按菜单拦截,javascript-在Android上长按时禁用上下文菜单
  6. 图片鉴黄大赛上线,请开始你的表演
  7. c语言float如何做减法,利用c语言设计开发一个简单计算器,可进行加减乘除运算....
  8. SQL 不常用的一些命令sp_OACreate,xp_cmdshell,sp_makewebtask
  9. OpenCV---圆检测
  10. axvspan函数--Matplotlib
  11. 5分钟转换PDF为图片
  12. linux查看网卡是down还是up,查看Linux下网卡链接状态(up仍是down)?
  13. AsyncTask异步加载给视频截取第一帧图片
  14. java游戏 飞机对战
  15. 业界首个,冲量在线联合海光信息发布异构隐私计算一体机!
  16. VS Code C++ 代码格式化方法(clang-format)
  17. 每天五分钟机器学习:随着算法迭代次数动态调整学习率
  18. RISC-V学习基础(五)
  19. 中粮粮油化工厂人员定位解决方案,解决目前化化工厂普遍问题-新导智能
  20. mybatis从入门到精通(刘增辉著)-读书笔记第四章

热门文章

  1. 问道虚拟机 登陆不上去了?无法运行?如何解决?
  2. Oracle数据库编程
  3. Unity 加载 AB包的缓存问题
  4. 湖南多校对抗赛(csu 1560)
  5. 英语口语练习六十一之全神贯注”的英语表达
  6. 笔记本电脑选购参考因素
  7. [881]内存不足RuntimeError: CUDA out of memory. Tried to allocate 16.00 MiB (GPU 0; 2.00 GiB total cap...
  8. SQL*Plus 学习笔记——常用编辑命令
  9. HTML blockquote元素
  10. Java 图形界面基础