java 初始代码块

class text01{  
    public text01(int i){  
        System.out.println("Test01 of constractor : " + i);  
    }  
}  

public class text02 {

   private text01 t1 = new text01(1);  
   private int n = 10;  
     
   public text02(){  
       System.out.println("Test02 of constructor : " + n);  
   }  
   private text01 t2 = new text01(2);  
   public static void main(String[] args) {  
      text02 test = new text02();  
   }  
 
}


  1. 输出的结果为:  
  2. Test01 of constractor 1  
  3. Test01 of constractor 2  
  4. Test02 of constructor 10  

通过输出,可见当生成Test02的实例test时,它并不是首先调用其构造方法而是先是成员变量的初始化,而且成员的初始化的顺序以成员变量的定义顺序有关,先定义的先初始化,初始化后再调用构造方法。其实成员变量的初始化,在类的所有方法调用之前进行,包括构造方法

当类中有Static 修饰的成员呢?测试下面一段代码:

  1. public class Test03 ...{  
  2.     private int i1 printCommon();  
  3.     private static int i2 printStatic();  
  4.       
  5.     public Test03()...{  
  6.           
  7.      
  8.     public static int printCommon()...{  
  9.         System.out.println("i1 is init!");  
  10.         return 1 
  11.      
  12.     public static int printStatic()...{  
  13.         System.out.println("i2 is init!");  
  14.         return 2 
  15.      
  16.     public static void main(String[] args) ...{  
  17.         Test03 new Test03();  
  18.      
  19.  
  20.   
  21. 输出结果为:  
  22. i2 is init!  
  23. i1 is init!  

可见static的成员比普通的成员变量先初始化。


我们都知道,如果一个类的成员变量没有在定义时,系统会给予系统默认的值,有=号的就直接给予右值,系统在给予初值和=号给予值这2中方式,在执行时间上有先后吗?为了测试,我编写了如下代码:

  1. public class Test04 ...{  
  2.     private static Test04 t1 new Test04();  
  3.     private static int i1;  
  4.     private static int i2 2 
  5.       
  6.     public Test04()...{  
  7.         i1++;  
  8.         i2++;  
  9.      
  10.       
  11.     public static void main(String[] args) ...{  
  12.         Test04 t2 new Test04();  
  13.         System.out.println("t2.i1 " t2.i1);  
  14.         System.out.println("t2.i2 " t2.i2);  
  15.      
  16.  
  17. 我们先预计一下输出,可能有几种答案:233322  
  18. 执行代码后:  
  19. t2.i1 2  
  20. t2.i2 3  

为什么是2和3呢?其实代码的执行顺序是这样的:首先执行给t1,i1,i2分别给予初始值null,0,0,再执行
Test04 t1 =new Test04(),这样i1++,i2++被执行,i1,i2都变为1,执行完毕后接着执行int i1; i1,i2的值仍然是1,1,当执行int i2 = 2时i2被赋予了值,即i1 = 1,i2=2;再执行Test04 t2 = new Test04(),i1,i2再执行++,此时i1 =2,i2 =3,输出i1,i2,结果就是:t2.i1 = 2,t2.i2 = 3。 通过上面的代码我们可以认为系统默认值的给予比通过等号的赋予先执行。

 当生成一个子类时,大家到知道会调用父类的构造方法。如果子类和父类中都有Static的成员变量呢,其实我们在深入分析一个类的内部初始化后,对于存在父类的类的初始化其实原理都一样,具体以下面的代码为例:

public class SuperClass {
static{  
        System.out.println("SuperClass of static block");  
    }  
      
    public SuperClass(){  
        System.out.println("SuperClass of constracutor");  
    }  
}  
public class SubClass extends SuperClass{  
   static{  
       System.out.println("SubClass of static block");  
   }        
   public SubClass(){  
       System.out.println("SubClass of constracutor");  
   }  
     
   public static void main(String[] args){
    SuperClass t = new SubClass();  
   }  
}  



// SuperClass of static block
// SubClass of static block
// SuperClass of constracutor
// SubClass of constracutor


可见当父类,和子类有Static时,先初始化Static,再初始化子类的Static,再初始化父类的其他成员变量->父类构造方法->子类其他成员变量->子类的构造方法。
父 类上层还有父类时,总是先执行最顶层父类的Static-->派生类Static-->派生类 Static-->.......-->子类Static-->顶层父类的其他成员变量-->父类构造方法--> 派生类的其他成员变量 --> 派生类构造方法--> ...............-->子类其他成员变量-->子类构造方法

总结:

  (1) 在一个不存在继承的类中:初始化static变量,执行static初始化快-->初始化普通成员变量(如果有赋值语句),执行普通初始化块-->构造方法

  (2)在一个存在继承的类中:初始化父类static成员变量,运行父类static初始化块-->初始化子类static成员变量,运行子类static初始化块-->初始化父类实例成员变量(如果有赋值语句),执行父类普通初始化块-->父类构造方法-->初始化子类实例成员变量(如果有赋值语句)及普通初始化块-->子类构造方法。

注意:其中变量初始化(赋值)和初始化块的执行与相关语句在源码中的放置顺序一致,不过变量声明会最先执行,参考 http://www.189works.com/article-52232-1.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值