Java程序初始化的顺序

来源:互联网 发布:python开发工具 编辑:程序博客网 时间:2024/05/22 00:12

此处讨论Java程序初始化的顺序。

一、实例化对象时:

1.对象所在类的所有成员变量首先都要进行初始化。

这里的成员变量包括实例变量和类变量。即所有的变量都要先初始化。

2.所有的类成员完成初始化,才会调用对象所在类的构造函数创建对象。

类成员包括成员变量和成员方法,即所有的四类变量和方法:实例变量和类变量,实例方法和类方法,全部初始化完毕。

二、Java程序初始化顺序的原则有三,优先级依次递减:

1.静态对象(变量)优于非静态对象(变量)初始化,其中静态对象(变量)只初始化一次。

2.父类优先于子类。

3.按成员变量的定义顺序进行初始化,即变量定义散布于方法定义之中,它们依然在任何方法(包括构造函数)被调用之前先被初始化。

三、Java程序初始化工作可以在许多不同的代码块中来完成,他们执行的顺序如下:

父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数

/** * @author delia * @create 2016-05-11 上午11:30 */class A {    int a = 10;    A() {        System.out.println("A()");        print();           //此处是调用子类的还是父类的?    }    void print() {        System.out.println("A.print()");        System.out.println(a);    }}class B extends A {    int a = 20;    B() {        System.out.println("B()");        print();    }    void print() {        System.out.println("B.print()");        System.out.println("super.a="+super.a);        System.out.println("this.a="+this.a);        System.out.println("a="+a);//没有this,super,默认是this.a    }}
public class Test {    public static void main(String[] args) {        A demo = new B();        System.out.println("instance.a="+demo.a);//成员变量无法实现多态,取值父类还是子类不取决于对象的类型,而是        //取决于所定义变量的类型,这是在编译期间确定的(多态是运行期间).由于demo所属的类型为A,demo.a指的是A类中定义        //的a,所以输出10    }}/*执行结果:    A()    B.print()    super.a=10    this.a=0    a=0    B()    B.print()    super.a=10    this.a=20    a=20    demo.a=10执行顺序:    1.A a = new B(),调用B的构造函数之前先调用父类A的构造函数A();    2.A()中调用了print()方法,该方法在子类B()中被覆盖,调用B的print()函数.此时在B中的变量a没有初始化,默认为0.注意,不是在A.a没有初始化,而是B.a没有初始化    3.A()执行完毕,执行B的构造函数B(),及里面的print()方法,此时也是B的print()方法.    实例化对象的初始化顺序里,成员变量按定义顺序进行初始化,在任何方法(包括构造函数)被调用之前被初始化. */


对象创建类型举例:

总结一下对象的创建过程,假设有个叫Dog的类:(静态初始化只在必要时刻才会进行,即调用静态X的时候)

1.即使没有显示的使用static关键字,构造器实际上也是静态方法。因此,在首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/域首次被访问时,Java解释器必须查找类路径以定位Dog.class文件。

2.然后载入Dog.class(创建一个Class对象),有关静态初始化的所有动作都会执行。故静态初始化只会在Class对象首次加载的时候进行一次。

3.当用new Dog()创建对象的时候,首先在堆上为Dog对象分配足够的存储空间。

4.这块存储空间被清零,这就自动地将Dog对象中的所有基本类型数据都设置了默认值(对数字来说是0,对布尔型和字符型也相同),而引用被设置成null.

5.执行所有出现于字段定义处的初始化操作。

6.执行构造器。

其他:

1.局部变量必须初始化,否则报错。

2.成员变量可以不初始化,编译器给默认的初始值

3.可以定义时初始化。

4.可以构造器初始化。

5.无法阻止自动初始化的进行,它将在构造器被调用之前发生。如

public class Counter{

int i ;

        Counter()  { i = 7; }

那么i将首先被置0,后变成7。




0 0
原创粉丝点击