java 程序初始化顺序

来源:互联网 发布:光猫超级密码开启端口 编辑:程序博客网 时间:2024/05/01 09:12

1. java程序初始化(针对成员变量和代码块来讲)顺序一般遵循三个原则(其优先级依次降低):

① 静态 优于 非静态

② 父类 优于 子类

③ 按照顺序

即使变量或者代码块(用{}包起来的)的定义分散于方法定义之中,它们依然在任何方法(包括构造函数)被调用之前先初始化。

只有在变量和代码块完成初始化之后,才会调用构造方法。

2.以下这个例子说明:优先级:静态变量(代码块)> 非静态变量(代码块)> 构造函数  这种优先级并不会受代码顺序的影响

但是同一级当中,就必须受到顺序的影响了,比如在这个例子之中,静态变量i的定义必须在静态代码块之前,否则程序不能识别静态代码块中的i

产生编译错误:illegal forword reference(非法前向引用)

    static{        i=0;//可以对在static{}之后定义的变量,在static{}中对其进行赋值操作        System.out.println(i);//但不可以对其进行访问操作,编译器会提示“非法前向引用”Error    }    static int i = 0;//在这里进行定义和初始化


public class Test {         //构造函数    Test(){        System.out.println("Test constructor");    }    //非静态成员变量    int j = 22;        //非静态代码块    {        System.out.println("Test non-static"+j);    }        //静态成员变量    static int i = 11;        //静态代码块    static{        System.out.println("Test static"+i);    }    public static void main(String[] args){        Test test = new Test();    }}

输出结果是:

Test static11
Test non-static22
Test constructor

3.在有父子继承关系中的初始化优先级顺序是:父类静态变量(代码块)> 子类静态变量(代码块)> 父类非静态变量(代码块) >父类构造函数 > 子类非静态变量(代码块)> 子类构造函数

public class Test {    //构造函数    Test(){        System.out.println("parent Test constructor");    }    //非静态成员变量    int j = 22;    //非静态代码块    {        System.out.println("parent Test non-static"+j);    }    //静态成员变量    static int i = 11;    //静态代码块    static{        System.out.println("parent Test static"+i);    }}
<pre name="code" class="java">public class Test2 extends Test {    //构造函数    Test2(){        System.out.println("Test2 constructor");    }    //非静态成员变量    int j = 22;    //非静态代码块    {        System.out.println("Derived Test2 non-static"+j);    }    //静态成员变量    static int i = 11;    //静态代码块    static{        System.out.println("Derived Test2 static"+i);    }    public static void main(String[] args){        Test2 test2 = new Test2();    }}



输出结果为:

parent Test static11
Derived Test2 static11
parent Test non-static22
parent Test constructor
Derived Test2 non-static22
Test2 constructor


未完待续:从JVM类加载机制的角度去分析

------------------------------update:2015.5.11------------------------------

1.从JVM类加载机制的角度去分析:

在类加载的初始化阶段(initialization):是执行 类构造器(class constructor)即 <clinit>() 方法 的过程,这个过程系统自动收集所有类变量(static field)的赋值动作静态语句块(static{ })中的语句。所以,在类加载阶段就初始化了类变量和静态代码块,当然顺序依然是先父类后子类。

而在构建对象的时候(比如new一个对象时)才执行 非静态变量负值语句和非静态代码块语句,然后再执行对象的构造器constructor

2.更正之前2中关于灰色删除语句部分的叙述。









0 0
原创粉丝点击