Java 类成员的初始化顺序

前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究。

 

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初始化顺序为:

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

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

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

 

 

Java初始化顺序如图:

 

参考文献:

Java初始化顺序

Java 类成员的初始化顺序的更多相关文章

  1. Java中类成员变量初始化顺序

    一. 定义处默认初始化vs构造函数中初始化 java中类成员变量支持在声明处初始化,也可以在构造函数中初始化,那么这两者有什么区别呢?看下面例子 public class FieldsInit { p ...

  2. Java类的变量初始化顺序

    大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台 ...

  3. java类中元素初始化顺序

    结论:对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器. public class Test4 { @Tes ...

  4. java类及实例初始化顺序

    1.静态变量.静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只在类加载时,初始化一次) 2.非静态变量.非静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只要 ...

  5. java类对象的初始化顺序

    在下面这个例子中,我们分别在父类和子类中测试了静态代码块.普通代码块.静态成员变量.普通成员变量.构造器.静态内部类. 一:代码块及变量测试 class Field{ public static St ...

  6. c++ 类成员的初始化顺序

    class TestClass1 { public: TestClass1() { cout << "TestClass1()" << endl; } Te ...

  7. java类中元素初始化顺序详解

    父类静态变量父类静态块子类静态变量子类静态块父类普通变量父类普通块父类构造方法子类普通变量子类普通块子类构造方法

  8. java类中成员的初始化顺序(一)

    类被创建之后的成员的初始化顺序到底是怎么样的? 首先 不考虑继承 package com; public class DemoOne { /** * 关于类的初始化顺序 */ //不考虑继承结构的情况 ...

  9. java中的多构造函数以及类字段的初始化顺序

    1.同一个类可以有多个构造函数,多个构造函数之间通过参数来区分.这是方法重载的一个实例.构造函数之间可以相互调用. 2.类的初始化块:可以在类中使用“{”和“}”将语句包围起来,直接将其作为类的成员. ...

随机推荐

  1. 各种ORM安装

    1.EF安装 2.PetaPoco安装 Install-Package PetaPoco 3.

  2. 利用shell脚本统计文件中出现次数最多的IP

    比如有如下文件test.txt 1  134.102.173.43 2  134.102.173.43 3  134.102.171.42 4  134.102.170.9 要统计出现次数最多的IP可 ...

  3. QT程序在windows下部署发布

    转载:http://www.cnblogs.com/Fan_Fan/archive/2010/05/29/1746860.html QT程序在windows下部署发布 以下包括了部分网上收集的,以及q ...

  4. 标准库 - fmt/scan.go 解读

    // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a B ...

  5. 如何通过apt-get获得安装包的源码

    有时候我们需要获得某个可执行程序的源码,而不仅仅是一个可执行程序,比如我们想获取tree这个工具的源码,这时候就可以采用下面的命令: sudo apt-get source tree pengdl@d ...

  6. 快递鸟顺丰电子面单接口API-JAVA

    一.电子面单对接案例 1.接口描述 接口支持的消息接收方式:HTTP POST 请求方法的编码格式(utf-8):"application/x-www-form-urlencoded;cha ...

  7. IOS开发 xcode报错之has been modified since the precompiled header was built

    转载的文章  很实用 IOS开发xcode报错之has been modified since the precompiled header was built 今天做百度地图的时候第一次发现下面错误 ...

  8. UIPickerView 简单操作和实际应用

    1.UIPickerView 选择指示器控件 //选择器的初始化 UIPickerView * pickerView = [[UIPickerView alloc] initWithFrame:CGR ...

  9. nc命令详解

    NetCat,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本.因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小).功能实用,被设计为一个简单.可靠的网络工具,可通 ...

  10. hdu 3308 LCIS 线段树

    昨天热身赛的简单版:LCIS.昨天那题用树链剖分,不知道哪里写错了,所以水了水这题看看合并.更新方式是否正确,发现没错啊.看来应该是在树链剖分求lca时写错了... 题目:给出n个数,有两种操作: 1 ...