随笔-95  评论-31  文章-10  trackbacks-0
如果一个类有父类,并且该类里面存在super、this、非静态代码块,静态代码块,静态变量,非静态变量,那么初始化这个类的时候顺序是什么?
示例:

package com.lx;

public class Son extends Parent
{    
    
final static Son INSTANCE = new Son(2.8);
    
static double initCount =20;
    
double currentCount;
    {
        currentCount 
= 15;
    }
    
    
static{
        initCount 
=22.8;
    }
    
    
public Son(){
        System.out.println(
"执行son的无参构造");
    }
    
    
public Son(double discount){
        
this();
        System.out.println(
"执行son的构造函数");
        System.out.println(currentCount);
        currentCount 
= initCount - discount;
        System.out.println(currentCount);
    }
    
    
public static void main(String[] args)
    {
        System.out.println(Son.INSTANCE.currentCount);
        
//        Son son = new Son(1.8);
    }

}
package com.lx;

public class Parent
{
    double a;
    static double b ;
    
    public Parent(){
        System.out.println(a);
        System.out.println(b);
        System.out.println("执行parent的无参构造");
    }
    
    {
        a = 2.33;
    }
    
    static{
        b = 33.33;
    }
}

顺序是首先调用父类的构造,然后进行static的和非static的初始化,这两步都合并到构造里面进行,初始化的赋值取决于在类里面的顺序,但是都在构造执行的前面执行。
如果一定要给个顺序:那么是这样
分配子类的变量空间赋值为null或者为0
接着super父构造,父构造里面执行前先分配内存空间并赋值,执行构造
然后回到子类,进行变量的赋值操作,顺序为类里面代码的顺序(指的是代码块和赋值语句的顺序),然后才会执行构造函数里面的内容。
其中有一点:非静态的代码块以及实例变量的赋值语句,执行在构造函数内容之前,super之后。然而静态的代码块以及类变量的赋值语句,与new 构造无关,只和代码里面的顺序有关,但是
new 构造会触发static的赋值时机,即在类中从上到下进行static的赋值,如果static的变量赋值不是上面代码那样static Son INSTANCE = new Son(2.8);那么同样会在构造函数之前进行赋值,然后在调用构造函数内容。即像父类Parent输出那样,其中a=2.33 b=33.33 而不是想象中的a=2.33 b=0.0
但是子类Son里面,触发static初始化赋值时机后,从上到下开始赋值但是INSTANCE = new Son(2.8);执行构造 同样会触发static的变量赋值,但是发现必须要先执行new Son(2.8)进行INSTANCE赋值,但是initCount还没有进行赋值,只是简单的初始化分配了内存值为0.0,所以就输出了负数。
最后main里面执行Son son = new Son(2.8)的时候,仍然进行了两次对INSTANCE的赋值,第一次出现的就是负数,第二次出现的是正数了,因为initCount已经赋值了。

所以补充一点:构造进行初始化的时候,会对所有的静态和非静态代码块和赋值语句,进行赋值,这一步执行操作在super之后,构造函数内容之前。非静态代码块和实例变量赋值,无论如何都会执行,而静态的代码块和类变量赋值则不一定,这个可以把
final static Son INSTANCE = new Son(2.8);
修改为Son INSTANCE = new Son(2.8);
再执行的话,会发现一直在进行new Son(2.8)的操作,一直到抛出
Exception in thread "main" java.lang.StackOverflowError异常,这说明构造初始化的时候,会强制性的进行非静态代码块或者实例变量的赋值。



posted on 2012-06-12 20:31 朔望魔刃 阅读(287) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航: