Java初始化顺序

作者:wota

来源:http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html(点击文末阅读原文前往)

1 无继承情况下的Java初始化顺序:

class Sample

{
      Sample(String s)
      {
            System.out.println(s);
      }
      Sample()
      {
        System.out.println("Sample默认构造函数被调用");
      }
}

class Test{

 static Sample sam=new Sample("静态成员sam初始化");
      Sample sam1=new Sample("sam1成员初始化");
 static{
            System.out.println("static块执行");
 if(sam==null)System.out.println("sam is null");
            sam=new Sample("静态块内初始化sam成员变量");
            }
      Test()
      {
            System.out.println("Test默认构造函数被调用");
      }
}

//主函数

 public static void  main(String  str[])
{
     Test a=new Test();
 }

输出结果为:

静态成员sam初始化 -----静态成员初始化

static块执行 -----静态块被执行

静态块内初始化sam成员变量 ----静态块执行

sam1成员初始化 -----普通成员初始化

Test默认构造函数被调用 -----构造函数执行

由此可以得出结论:

a 静态成员变量首先初始化(注意,Static可以看做一个静态成员,其执行顺序和其在类中申明的顺序有关)

b 普通成员初始化

c 执行构造函数。

对于静态成员(static块可以看成普通的一个静态成员,其并不一定在类初始化时首先执行)和普通成员,其初始化顺序只与其在类定义中的顺序有关,和其他因素无关。

例如下面的例子:

class Test{
 static{
            System.out.println("static 块 1  执行");
            }
 static Sample staticSam1=new Sample("静态成员staticSam1初始化");
      Sample sam1=new Sample("sam1成员初始化");
 static Sample staticSam2=new Sample("静态成员staticSam2初始化");
 static{
            System.out.println("static 块 2  执行");
            }
      Test()
      {
            System.out.println("Test默认构造函数被调用");
      }
      Sample sam2=new Sample("sam2成员初始化");
}

则结果为:

static 块 1 执行

静态成员staticSam1初始化

静态成员staticSam2初始化

static 块 2 执行

--------静态成员

sam1成员初始化

sam2成员初始化

--------普通成员

Test默认构造函数被调用

--------构造函数

2 Java继承情况下的初始化顺序:

class Test{
 static{
            System.out.println("父类static 块 1  执行");
            }
 static Sample staticSam1=new Sample("父类 静态成员staticSam1初始化");
      Sample sam1=new Sample("父类 sam1成员初始化");
 static Sample staticSam2=new Sample("父类 静态成员staticSam2初始化");
 static{
            System.out.println("父类 static 块 2  执行");
            }
      Test()
      {
            System.out.println("父类 Test默认构造函数被调用");
      }
      Sample sam2=new Sample("父类 sam2成员初始化");
}
class TestSub extends Test
{
 static Sample staticSamSub=new Sample("子类 静态成员staticSamSub初始化");
      TestSub()
      {
            System.out.println("子类 TestSub 默认构造函数被调用");
      }
      Sample sam1=new Sample("子类 sam1成员初始化");
 static Sample staticSamSub1=new Sample("子类 静态成员staticSamSub1初始化");
 static{System.out.println("子类 static 块  执行");}
      Sample sam2=new Sample("子类 sam2成员初始化");
}

执行结果:

父类 static 块 1 执行

父类 静态成员staticSam1初始化

父类 静态成员staticSam2初始化

父类 static 块 2 执行

--------父类静态成员初始化

子类 静态成员staticSamSub初始化

子类 静态成员staticSamSub1初始化

子类 static 块 执行

-------子类静态成员初始化

父类 sam1成员初始化

父类 sam2成员初始化

父类 Test默认构造函数被调用

-------父类普通成员初始化和构造函数执行

子类 sam1成员初始化

子类 sam2成员初始化

子类 TestSub 默认构造函数被调用

-------父类普通成员初始化和构造函数执行

由此得出Java初始化顺序结论:

1 继承体系的所有静态成员初始化(先父类,后子类)

2 父类初始化完成(普通成员的初始化-->构造函数的调用)

3 子类初始化(普通成员-->构造函数)

Java初始化顺序如图:

有的朋友问到内部的机制,上述的初始化顺序是由下面的几条规则决定的:

1.首先初始化静态域是因为静态域是放在方法区和class对象在一起的。 2.由于类加载的时候,会向上查找基类,因为子类的初始化依赖于基类首先初始化。所以会首先发生“基类->子类"顺序的类加载,类加载过程中,顺便完成了静态域的初始化。 3.另外一条规则是初始化块和域的初始化按照声明的顺序进行。

详见thinking in java中译本第四版的P147页。

原文发布于微信公众号 - java达人(drjava)

原文发表时间:2017-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐百川的学习频道

C++学习笔记 类型声明

类型别名 typedef关键字 typedef关键字是继承自C语言的特性,利用它我们可以为一个类型起别名,一般用于将复杂类型简化。举个简单的例子,将int类型定...

1939
来自专栏运维技术迷

PHP-循环

php中,一共提供了以下循环语句: while:只要指定的条件成立,则循环执行代码块(在不确定循环次数的情况下使用) do….while:首先执行一次代码块,然...

2955
来自专栏osc同步分享

前缀、中缀、后缀表达式

前缀、中缀、后缀表达式,它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。对计算机来说中缀表达式是很复...

3327
来自专栏开发与安全

从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数

一、构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一)、对象成员及其初始化 #inclu...

2680
来自专栏啸天"s blog

Java中的关键字

1505
来自专栏河湾欢儿的专栏

第四节检测数据类型4种方式

881
来自专栏前端知识分享

第174天:面向对象——公有属性、私有属性和静态属性

1283
来自专栏深度学习思考者

Python学习(三) 八大排序算法的实现(下)

本文Python实现了插入排序、基数排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序的后面四种。 上篇:Python学习(三) 八大排序算...

24210
来自专栏null的专栏

PHP基础——PHP数组

PHP数组与其他语言的数组有些不同,在PHP中,数组包含两种类型的数组: 数字索引数组 关联数组 其中,数字索引数组是指其key为数字,而后者可以使用字符串作为...

3696
来自专栏PHP在线

PHP字符串和数组操作函数

str_split() 函数把字符串分割到数组中。 stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。 stripcslas...

3937

扫码关注云+社区

领取腾讯云代金券