目录java
在程序设计中,让数据域正确地执行初始化一直是一个亘古不变的真理。
那么,有哪些手段能够初始化数据域呢:测试
本篇探讨关于Java中的初始化块的注意点:Java中的初始化块是类中的一种成员,可是既没有名字,也没有标识,不可以被调用,它仅仅只是在建立Java对象时隐式执行初始化。this
{}
包起代码,被包住的就是初始化代码,总体就是一个初始化块。声明实例变量时指定默认值和普通初始化块都被看作是对象的初始化代码,按前后顺序执行。设计
若是多个重载的构造器有相同且与传入形参无关的语句能够一块儿提入初始化块。code
public class NormalBlock { int a = 5; { // a = 6; System.out.println("初始化块以后的a为"+a); } // { // int a = 8; // System.out.println("初始化块中从新定义了一个a?"+a); // } NormalBlock(){ System.out.println("构造器中赋a的值为"+a); } } class NormalTest{ public static void main(String[] args) { new NormalBlock(); } }
初始化块以后的a为5 构造器中赋a的值为5
能够看到,在这个例子中,声明实例变量指定默认值也被看做初始化代码,且依次执行,先初始化块,后构造器。(能够试着调换它们的位置验证一下哈)orm
初始化块以后的a为6 初始化块中从新定义了一个a?8 构造器中赋a的值为6
个人疑惑点在于,我一开始觉得,我在第二个代码块中定义的和以前同名的变量a是同一个(然而并非)这样也就算了,初始化代码以后,执行构造器时,调用了a,那么这时这个a调用的是哪一个呢,因而产生疑惑,但愿知道的小伙伴能够为我指点迷津。对象
ilegal forward reference
,即前向引用错误,以下图。{ age = 50; if(age>40) System.out.println("Father类的初始化块且age>40"); System.out.println("Father类的第一个初始化块"); } int age =20;
产生缘由:是由于在尚未定义该变量时,就引用了它,因此为了不这样的错误,尽可能将初始化块放在成员变量声明以后。继承
和普通的对应的就是静态初始化块啦,也就是用static修饰的,也称为类初始化块。根据名称分析,类初始化块负责对类进行初始化,而普通初始化块负责对对象执行初始化。it
static{}
的格式包围对类变量的初始化。关于初始化块与构造器的前后调用顺序,结合代码来理解一会儿。程序设计
package com.my.pac17; /** * @auther Summerday */ public class A { { System.out.println("A.instance initializer"); } static { System.out.println("A.static initializer"); } public A() { System.out.println("A.A"); } } class B extends A { { System.out.println("B.instance initializer"); } static { System.out.println("B.static initializer"); } public B() { System.out.println("B.B"); } public B(String m) { this(); System.out.println("B.B," + m); } } class C extends B { { System.out.println("C.instance initializer"); } static { System.out.println("C.static initializer"); } public C() { super("ccc"); System.out.println("C.C"); } } class BTest { public static void main(String[] args) { new C(); System.out.println("*******"); new C(); } }
/*测试结果*/ A.static initializer B.static initializer C.static initializer /*类初始化阶段,限制性最顶层父类的静态初始化块 而后依次向下,直到执行当前类的静态初始化块*/ A.instance initializer A.A B.instance initializer B.B//调用B的无参构造器 B.B,ccc//调用B的带参构造器 C.instance initializer//最后执行C C.C /*对象初始化阶段,先执行最顶层父类的初始化块, 最顶层父类的构造器,而后依次向下,直到执行当前 类的初始化块、当前类的构造器*/ ******* //不用执行静态初始化语句 A.instance initializer A.A B.instance initializer B.B B.B,ccc C.instance initializer C.C