Java 类成员的初始化顺序
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中类成员变量初始化顺序
一. 定义处默认初始化vs构造函数中初始化 java中类成员变量支持在声明处初始化,也可以在构造函数中初始化,那么这两者有什么区别呢?看下面例子 public class FieldsInit { p ...
- Java类的变量初始化顺序
大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台 ...
- java类中元素初始化顺序
结论:对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器. public class Test4 { @Tes ...
- java类及实例初始化顺序
1.静态变量.静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只在类加载时,初始化一次) 2.非静态变量.非静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只要 ...
- java类对象的初始化顺序
在下面这个例子中,我们分别在父类和子类中测试了静态代码块.普通代码块.静态成员变量.普通成员变量.构造器.静态内部类. 一:代码块及变量测试 class Field{ public static St ...
- c++ 类成员的初始化顺序
class TestClass1 { public: TestClass1() { cout << "TestClass1()" << endl; } Te ...
- java类中元素初始化顺序详解
父类静态变量父类静态块子类静态变量子类静态块父类普通变量父类普通块父类构造方法子类普通变量子类普通块子类构造方法
- java类中成员的初始化顺序(一)
类被创建之后的成员的初始化顺序到底是怎么样的? 首先 不考虑继承 package com; public class DemoOne { /** * 关于类的初始化顺序 */ //不考虑继承结构的情况 ...
- java中的多构造函数以及类字段的初始化顺序
1.同一个类可以有多个构造函数,多个构造函数之间通过参数来区分.这是方法重载的一个实例.构造函数之间可以相互调用. 2.类的初始化块:可以在类中使用“{”和“}”将语句包围起来,直接将其作为类的成员. ...
随机推荐
- php-工厂模式(转)
针对自己的不足与加深php的认识,选择用php来研究各种设计模式. 今天就看了设计模式的介绍,并学习了工厂模式,因为工厂模式比较简单,也比较常用.工厂模式的最主要作用就是对象创建的封装.简化创建对象操 ...
- c#给用户控件添加事件处理程序
1.首先在usercontrol后台添加如下代码: public partial class MyControl: UserControl { //添加事件代理 public event ...
- 在应用程序中操作NorFlash
相对于操作NandFlash,操作NorFlash相对简单,因为基本不需要考虑坏块,NorFlash也没有OOB区域,也跟ECC没有一毛钱关系.它的读写擦除相对容易. int dealwithnor( ...
- Android实现定时器的方法
一.Handler 和 Thread package com.lstech.app; import android.app.Activity; import android.os.Bundle; im ...
- 二进制序列化框架easypack发布啦!
简介 easypack是基于boost.serialization的二进制序列化框架,使用极其方便. Examples 基本类型 int age = 20; std::string name = &q ...
- tachyon with spark
spark1.2.0 tachyon0.5.0 jdk1.7 scala2.10.4 1.装好spark.tachyon.jdk.scala 2.修改spark-env.sh添加Tachyon客户端 ...
- Handler发送消息
Handler发送消息小结 字数283 阅读210 评论0 喜欢1 obtainMessage()得到一个Message对象. 创建一个Message然后发送是这么写的: Message msg = ...
- 【Linux/Ubuntu学习6】unbuntu 下载android源码
在Windows下安装Cygwin,通过Cygwin也可在Windows里通过本文的下载步骤下载Android源码. 以下为在Ubuntu下下载Google Android4.4源码的步骤: 1. 安 ...
- CGFloat、CGPoint、CGSize和CGRect
CGFloat:是表示浮点数类型. CGPoint:表示二维坐标的点.通过x和y坐标定义.点表示位置值. CGSIZE:表示矩形的宽度和高度.通过宽度和高度来定义. CGRect: 表示矩形的位置和大 ...
- 【转】SQL 语句:Alter table
转载自:http://www.w3school.com.cn/sql/sql_alter.asp ALTER TABLE 语句 ALTER TABLE 语句用于在已有的表中添加.修改或删除列. SQL ...