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. isinstance和issubclass,__getattribute__,__getitem__,__setitem__,delitem__,__str__(三十五)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象 issubclass(sub, super)检查sub类是否是 super 类的派生类 class Foo: def __ ...

  2. 窗体焦点监听事件WindowFocusListener

      public class Demo extends JFrame { JLabel label;//定义变量,以便在自定义方法类中调用 public Demo() { setBounds(100, ...

  3. 在Linux上安装Elasticsearch Kibaba.md

    在Linux上安装Elasticsearch Kibaba Kibana是一个开源为elasticsearch 引擎提供数据和数据分析 1.下载安装 切换到root账户,按顺序依次执行以下命令 rpm ...

  4. ElasticSearch文档操作介绍三

    ElasticSearch文档的操作 文档存储位置的计算公式: shard = hash(routing) % number_of_primary_shards 上面公式中,routing 是一个可变 ...

  5. python字典遍历的几种方法

    (1)遍历key值 >>> a {'} >>> for key in a: print(key+':'+a[key])   a:1 b:2 c:3 >> ...

  6. Linux实战型企业运维工程师试题测评

    Linux实战型企业运维工程师试题答案 作者:尹正杰      最近在网上看到了一套有意思的面试题,我们一起来看一下这些题怎么破吧,哈哈~我先放在这里,有时间了一起来看看.多学点东西终究是没有坏处的! ...

  7. SQL 对大小写不敏感!

    一定要记住,SQL 对大小写不敏感!

  8. JAVA求解全排列

    一,问题描述 给定一个字符串,求出该字符串的全排列. 比如:"abc"的全排列是:abc.acb.bac.bca.cab.cba 二,实现思路 采用递归的方式求解.每次先选定一个字 ...

  9. C#析构函数与Dispose

    有几种不同的操作方式 方式一: namespace ConsoleApp1 {     class Test     {         ~Test()// 析构函数         {        ...

  10. linux4.10.8 内核移植(三)---裁剪内核

    一.裁剪内核 1.1 第一次修改 现在的内核大小为2.8M左右,要裁剪到2.0M以下,毕竟给内核分区就只有2.0M. 这两个设备我们没有,裁剪掉. 进入make menuconfig中,搜索mouse ...