1. 引言

了解Java初始化的顺序,有助于理解Java的初始化机制和内存机制

顺序:父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数(说明:static变量包括static变量和static代码块,按位置顺序执行)

2. 样例

2.1 无继承的类的初始化顺序

public class TestClass {

	public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
t2.f2(1);
t3.f3(1);
} static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
} // : StaticInitialization.java
// Specifying initial values in a
// class definition. class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
} void f(int marker) {
System.out.println("f(" + marker + ")");
}
} class Table {
static Bowl b1 = new Bowl(1); static{
System.out.println("Table() static 1");
} Table() {
System.out.println("Table()");
b2.f(1);
} void f2(int marker) {
System.out.println("f2(" + marker + ")");
} Bowl b10 = new Bowl(10); {
System.out.println("Table() non-static");
} Bowl b11 = new Bowl(11); static Bowl b2 = new Bowl(2); static{
System.out.println("Table() static 2");
}
} class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4); Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
} void f3(int marker) {
System.out.println("f3(" + marker + ")");
} static Bowl b5 = new Bowl(5);
}

输出的结果如下:

Bowl(1)
Table() static 1
Bowl(2)
Table() static 2
Bowl(10)
Table() non-static
Bowl(11)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)

2.2 有继承的类的初始化顺序

//: Beetle.java
// The full process of initialization. class Insect {
int i = 9;
int j;
Insect() {
prt("i = " + i + ", j = " + j);
j = 39;
}
static{
System.out.println("Insert static block0");
} static int x1 =
prt("static Insect.x1 initialized");
static int prt(String s) {
System.out.println(s);
return 47;
}
static{
System.out.println("Insert static block1");
}
} public class Beetle extends Insect {
int k = prt("Beetle.k initialized");
Beetle() {
prt("k = " + k);
prt("j = " + j);
}
static int x2 =
prt("static Beetle.x2 initialized");
static int prt(String s) {
System.out.println(s);
return 63;
}
public static void main(String[] args) {
prt("Beetle constructor"); //flag 1
Beetle b = new Beetle(); //flag 2
}
} ///:~

输出的结果如下:

Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39 //如果只把flag 1 那条语句注释掉,输出内容如下:
Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39 //如果只把flag 2 那条语句注释掉,输出内容如下:
Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
Beetle constructor

3. 总结

只要按照这个顺序:父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数(说明:static变量包括static变量和static代码块,按位置顺序执行), 去推导初始化执行顺序就能得到正确的执行答案数据。

注意点:

1.若仅仅执行static方法,则只会执行该类及其父类的所有静态变量,而且静态变量只会被执行一次

2.当对象被new出来时,才会开始初始化该类及其父类的所有变量,按照以上的说的顺序执行

3.成员或者静态static变量若申明时不赋值,会被初始化相应类型的默认值,例如int是0,String是null等

4.可以用debug模式直接断点调试,跟着走一遍,就能看到代码是怎么初始化变量的(当然,自己先演练一遍,效果更好)

4.参考

Thinking in Java P113, P158

Java的初始化执行顺序(父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数)的更多相关文章

  1. Java子类和父类的初始化执行顺序

    要明白子类和父类的初始化执行顺序,只需要知晓以下三点,就不会再弄错了. 1.创建子类对象时,子类和父类的静态块和构造方法的执行顺序为:父类静态块->子类静态块->父类构造器->子类构 ...

  2. 关于java中构造方法、实例初始化、静态初始化执行顺序

    在Java笔试中,构造方法.实例初始化.静态初始化执行顺序,是一个经常被考察的知识点. 像下面的这道题(刚刚刷题做到,虽然做对了,但是还是想整理一下) 运行下面的代码,输出的结果是... class ...

  3. Java程序初始化的顺序

    Java程序初始化的顺序 java程序初始化工作可以在许多不同的代码块中来完成(例如:静态代码块.构造函数等),他们执行的顺序如下: 父类静态变量 父类静态代码块 子类静态变量 子类静态代码块 父类非 ...

  4. 八、 Java程序初始化的顺序(一)

    今天在写构造器方法的时候,遇到了一个小问题,由这个问题引发了一连串的思考,在一个Java类中变量与类的初始化执行顺序是什么样的呢?## 发现问题 class Student{ private Stri ...

  5. java代码块执行顺序

    父类 public class Father { public Father() { System.out.println("父类构造PUBLIC father"); } stat ...

  6. C#类、静态类、静态变量,初始化执行顺序

    执行顺序: 类的静态变量 ↓ 类的静态构造函数 ↓ 类的普通变量 ↓ 基类的静态变量 ↓ 基类的静态构造函数 ↓ 基类的普通变量 ↓ 基类的构造函数 ↓ 类的构造函数

  7. 《Java程序员面试笔试宝典》之Java程序初始化的顺序是怎样的

    在Java语言中,当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象. Java程序的初始化一般遵循以下三个原则(以下三原则优 ...

  8. 《Java程序猿面试笔试宝典》之Java程序初始化的顺序是如何的

    在Java语言中.当实例化对象时.对象所在类的全部成员变量首先要进行初始化,仅仅有当全部类成员完毕初始化后,才会调用对象所在类的构造函数创建对象.    Java程序的初始化一般遵循以下三个原则(以下 ...

  9. 九、 Java程序初始化的顺序(二)

    之前的一篇博客里我写了关于在一个类中的程序初始化顺序,但是在Java的面向对象里,类之间还存在着继承的关系.所以关于程序的初始化顺序,我们可以再细划分为:父类静态变量,父类的静态代码块,父类构造器,父 ...

随机推荐

  1. dijkstra(最短路)和Prim(最小生成树)下的堆优化

    dijkstra(最短路)和Prim(最小生成树)下的堆优化 最小堆: down(i)[向下调整]:从第k层的点i开始向下操作,第k层的点与第k+1层的点(如果有)进行值大小的判断,如果父节点的值大于 ...

  2. [持续更新] 文章列表 Last Update: 8/21/2017

    1.前端 HTML5快速学习二 Canvas@20141125 HTML5快速学习一@20141122 2.ASP.NET(MVC) MVC5+EF6 完整教程17--升级到EFCore2.0@201 ...

  3. maveb安装与配置(win10)

    转载:https://www.cnblogs.com/eagle6688/p/7838224.html 看了几篇博客,感觉这篇博客写的含金量最高了,因为我电脑的系统是win10的,所以配置有细微的差别 ...

  4. Angular开发小笔记

    一.父组件怎么覆盖子组件的样式呢 1./deep/(不建议这么做,以后angular会取消,因为这样写不利于组件的独立性) 在父组件的scss里面写: :host{ 子组件名 /deep/ label ...

  5. python 的正则表达式指北

    正则表达式用来拆分字符串 >>> s = 'one1two2three3four4' >>> pattern = re.compile(r'\d+') >&g ...

  6. JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储

    一,介绍 自ActiveMQ5.4以来,KahaDB成为了ActiveMQ默认的持久化存储方式.相比于原来的AMQ存储方式,官方宣称KahaDB使用了更少的文件描述符,并且提供了更快的存储恢复机制. ...

  7. windows上使用mkdocs搭建静态博客

    windows上使用mkdocs搭建静态博客 之前尝试过用HEXO搭建静态博客,最近发现有个叫mkdocs的开源项目也是搭建静态博客的好选择,而且它支持markdown格式,下面简要介绍一下mkdoc ...

  8. C# 时间戳与时间相互转化

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 时间戳d ...

  9. flash GC

    所有应用程序都要管理内存.应用程序的内存管理包括用于确定何时分配内存,分配多少内存,何时将内容放入回收站,以及何时清空回收站的准则.MMgc是 Flash Player用于几乎所有内存分配工作的通用内 ...

  10. python之functools partial

    from functools import partial def aa(a,b,c): print ('a :',a) print ('b :',b) print ('c :',c) bb=part ...