您的位置:首页 > 编程语言 > Java开发

Java初始化顺序(静态变量、静态初始化块、实例变量、实例初始化块、构造方法)

2017-06-09 22:17 776 查看

1、执行顺序

1.1、一个类中的初始化顺序

类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

1.2、两个具有继承关系类的初始化顺序

父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

示例如下:(结果见注释)

class A {
public A() {
System.out.println("Constructor A.");
}

{
System.out.println("Instance Block A.");
}
static {
System.out.println("Static Block A.");
}

public static void main(String[] args) {
new A();/*
* Static Block A. Instance Block A. Constructor A.
*/
}
}

class B extends A {
public B() {
System.out.println("Constructor B.");
}

{
System.out.println("Instance Block B.");
}
static {
System.out.println("Static Block B.");
}

public static void main(String[] args) {
new A();/*
* Static Block A. Static Block B. Instance Block A. Constructor A.
*/
System.out.println();
new B();/*
* Instance Block A. Constructor A. Instance Block B. Constructor B.
*/// 静态成员和静态初始化块只会执行一次。
}
}


2、对变量值的影响

一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定?按1节中所述的执行顺序确定。

这里考虑初始化块在变量定义之前的情形,此时会造成迷惑。

初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。如:

static {
a = 3;
// int b=a;//Cannot reference a field before it is defined
// System.out.println(a);//Cannot reference a field before it is defined
}
static int a = 1;


“对变量值的影响”是指 对变量赋值的初始化块位于变量定义之前 时,变量的最终值根据变量定义时是否显示初始化而会有不同结果(若初始化块位于变量定义之后,那么变量的值显然很容易就确定了,不会造成迷惑)。如:

class Test {
static {
a = 3;
// int b=a;//Cannot reference a field before it is defined
// System.out.println(a);//Cannot reference a field before it is defined
b = 3;
}
static int a = 1;
static int b;

public static void main(String[] args) {
System.out.println(a);//1
System.out.println(b);//3
}
}


判断方法:

显示初始化内部隐含 定义变量和对变量进行赋值的初始化块两部分,所以初始化块和显示初始化哪个在后变量的最终值就是该值。

更多示例:

1:

class C {

static {
a = 2;
b = 2;
}
static int a;
static int b = 1;

public C() {
e = 3;
}

{
c = 2;
d = 2;
e = 2;
}
int c;
int d = 1;
int e = 1;

public static void main(String[] args) {
System.out.println(C.a);//2
System.out.println(C.b);//1
System.out.println(new C().c);//2
System.out.println(new C().d);//1
System.out.println(new C().e);//3
}


2:

class C {
public C() {
}

{
a = 3;
}
static {
a = 2;
}
static int a;
static int b;

public static void main(String[] args) {
System.out.println(C.a);// 2
System.out.println(new C().a);// 3
System.out.println(C.b);// 0
}
}


3:

class C {
// 以下关于静态初始化的
static {
a = 2;
}
static int a = 1;
static int b = 1;
static {
b = 2;
c = 2;
}
static int c;

{
d = 2;
}
int d = 1;
int e = 1;
{
e = 2;
f = 2;
}
int f;

public static void main(String[] args) {
System.out.println(C.a);// 1
System.out.println(C.b);// 2
System.out.println(new C().c);// 2
System.out.println(new C().d);// 1
System.out.println(new C().e);// 2
System.out.println(new C().f);// 2
}
}


3、总结

执行顺序:

1、类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

2、父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。

变量最终值:一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定:

1、按执行顺序

2、若对变量赋值的初始化块在变量定义前时:若变量显示初始化了则最终为显示初始化值,否则为初始化块的赋值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐