关闭

java 初始代码块

标签: java
163人阅读 评论(0) 收藏 举报
分类:

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
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

JAVA学习笔记(九)- 初始化块与静态代码块

初始化块/* * 初始化块 * 初始化变量方式:声明时、构造函数、代码块 * 使用static关键字修饰的代码块,称为静态代码块 * * 执行顺序:静态代码块>代码块>构造方法 * ...
  • wangzi11322
  • wangzi11322
  • 2015-03-23 10:22
  • 3439

Java中初始化块和静态初始化块的区别

http://www.cnblogs.com/woshijpf/articles/3632489.html 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:...
  • hotdust
  • hotdust
  • 2016-06-29 09:39
  • 494

java类的加载 初始化时机,已经静态代码块的执行时机

写了这么长时间java,总是不太清楚什么是类的加载,初始化,加载初始化又对应的是我们代码中的哪一段。还有就是静态代码块到底是在什么实际执行的。         首先类加载包括  装载(也叫加...
  • kai763253075
  • kai763253075
  • 2016-08-28 17:00
  • 1399

java中普通变量、静态变量、静态代码块初始化的顺序辨析

1.普通变量的初始化 看如下程序 class Window{ public Window(int maker) { System.out.println("Window("+maker+")...
  • woshiwanghao_hi
  • woshiwanghao_hi
  • 2013-10-24 12:51
  • 4277

掌握java中的三种代码块的定义及使用

掌握java中的三种代码块的定义及使用 代码块概念 代码块本身并不是一个很难理解的概念,实际上之前也一直在使用。所谓代码块是指使用“{}”括起来的一段代码,根据位置不同,代码块可以分为...
  • sqc3375177
  • sqc3375177
  • 2015-04-20 15:56
  • 5493

Java 静态代码块和非静态代码块

参考:http://uule.iteye.com/blog/1558891Java中的静态代码块是在虚拟机加载类的时候,就执行的,而且只执行一次。如果static代码块有多个,JVM将按照它们在类中出...
  • kunlyy
  • kunlyy
  • 2016-08-10 21:09
  • 1260

Java中初始块的执行顺序

在Java中除了使用构造器类对单个对象进行初始化操作外,我们还可以通过初始化块来实现。在一个类中可以有多个初始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。使...
  • u010695218
  • u010695218
  • 2015-03-12 18:59
  • 963

Java中局部代码块、构造代码块、静态代码块的区别?

package day08; /* * 代码块:在Java中,使用{}括起来的代码成为代码块 * 根据其位置和声明的不同,可以分为 * 局部代码块:局部位置,用于限定变量的生命周期 * ...
  • xiakexiaohu
  • xiakexiaohu
  • 2017-05-17 22:13
  • 968

Java类静态属性、静态块、非静态属性、非静态块、构造函数在初始化时的执行顺序

前言     今天在看Android ContentProvider实现的时候,突然想到了Java类在new的过程中,静态域、静态块、非静态域、非静态块、构造函数的执行顺序问题。其实这是一个很经典的...
  • zinss26914
  • zinss26914
  • 2014-12-15 00:07
  • 2473

java四种代码块

出自http://my.oschina.net/building/blog/99213
  • hirohrj123
  • hirohrj123
  • 2014-04-03 17:20
  • 1278
    个人资料
    • 访问:23538次
    • 积分:1220
    • 等级:
    • 排名:千里之外
    • 原创:78篇
    • 转载:40篇
    • 译文:13篇
    • 评论:0条
    最新评论