Java继承类的初始化顺序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java继承类的初始化顺序相关的知识,希望对你有一定的参考价值。

class Parent {

// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
protected int i = 9;
protected int j = 0;
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
//构造器
public Parent() {
System.out.println("父类--构造器");
System.out.println("i=" + i + ", j=" + j);
j = 20;
}
//静态方法
static void sPrint(){
System.out.println("父类静态方法初始化");
}
//方法
void Print(){
System.out.println("父类方法初始化");
}
}

public class Sub extends Parent {
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}

//初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
//构造器
public Sub() {
System.out.println("子类--构造器");
System.out.println("i=" + i + ",j=" + j);
}
static void sPrint(){
System.out.println("子类静态方法初始化");
}
//方法
void Print(){
System.out.println("子类方法初始化");
}
//程序入口
public static void main(String[] args) {
System.out.println("子类main方法");
new Sub();
}
}

 

output:

父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
子类main方法
父类--变量
父类--初始化块
父类--构造器
i=9, j=0
子类--变量
子类--初始化块
子类--构造器
i=9,j=20

 

 

由上可知,顺序:

(1)在其他任何事物发生之前,将分配给对象的存储空间初始化为2进制的0,并且加载类(当然就包括初始化类的static成员,因此先初始化static).

(2)再进入main()
(3)调用基类(并且递归调用,最先调用根基类)  =》先field 再 instance 再 constructor  , method不会初始化
(4)调用派生类主体。 =》 先field 再 instance 再 constructor  

 

 

参考:http://blog.sina.com.cn/s/blog_4cc16fc50100bjjp.html

 

 

 

附阿里B2B北京笔试题:

public class DispatchTest {
public static void main(String[] args) {
Base b = new Sub();
System.out.println(b.x);
}
}

class Base {
int x = 10;

public Base() {
this.printMessage();
x = 20;
}

public void printMessage() {
System.out.println("Base.x = " + x);
}
}

class Sub extends Base {
int x = 30;

public Sub() {
this.printMessage();
x = 40;
}

public void printMessage() {
System.out.println("Sub.x = " + x);
}
}

 

output:

0

30

20

 

 

这里由于在调用Base的构造器时,使用的是this.PrintMessage  ,this指代的是继承的Sub类,而此时Sub的x还没有初始化,所以第一个输出是0

第三个由于x不是方法,所以不是一个重写,不要考虑动态绑定,指代的就是Base的x

 

以上是关于Java继承类的初始化顺序的主要内容,如果未能解决你的问题,请参考以下文章

Java类的各种成员初始化顺序如:父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺

java 中类的加载顺序

java类的初始化顺序

Java,extends,继承

多重继承关系初始化顺序及初始化

多重继承关系初始化顺序及初始化