tbwshc

tbw

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  95 Posts :: 8 Stories :: 3 Comments :: 0 Trackbacks

常用链接

留言簿(4)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

java对象的初始化

小冬(珠海)11:02:48
我们知道一个对象可以有静态变量、变量、静态初始化块、初始化块,当我们创建一个对象时,它是怎么初始化的呢?按什么顺序初始化的呢?
 
  1. public class Test { 
  2.  
  3.      
  4.     // 静态变量 
  5.     public static String staticField = "静态变量"; // 变量 
  6.     public String field = "变量"
  7.     // 静态初始化块 
  8.     static { 
  9.         System.out.println(staticField); 
  10.         System.out.println("静态初始化块"); 
  11.     } 
  12.     // 初始化块 
  13.     { 
  14.         System.out.println(field); 
  15.         System.out.println("初始化块"); 
  16.     } 
  17.     // 构造器 
  18.     public Test() { 
  19.         System.out.println("构造器"); 
  20.     } 
  21.     public static void main(String[] args) { 
  22.         Test test = new Testb(); 
  23.  
  24.     } 
 
运行下代码,输出结果是:
静态变量
静态初始化块
变量
初始化块
构造器
 
 
由此可以看到,当new一个对象时,它并不是就是调构造方法,而是先初始化属性变量,我们把变量的定义先后顺序换下,再执行,会发现,静态的是先于非静态进行实始化的,那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?
我们先改下代码:
 
  1. public class Test { 
  2.  
  3.     public static TestA ta = new TestA(); 
  4.     // 静态变量 
  5.     public static String staticField = "静态变量"; // 变量 
  6.     public String field = "变量"
  7.     // 静态初始化块 
  8.     static { 
  9.         System.out.println(staticField); 
  10.         System.out.println("静态初始化块"); 
  11.     } 
  12.     // 初始化块 
  13.     { 
  14.         System.out.println(field); 
  15.         System.out.println("初始化块"); 
  16.     } 
  17.     // 构造器 
  18.     public Test() { 
  19.         System.out.println("构造器"); 
  20.     } 
  21.     public static void main(String[] args) { 
  22.         Test test = new Test(); 
  23.  
  24.     } 
  25.  
  26. class TestA { 
  27.     public TestA() { 
  28.         System.out.println("Test--A"); 
  29.     } 
 输出是:
Test--A
静态变量
静态初始化块
变量
初始化块
构造器
 
 
静态变量:static TestA ta = new TestA()在静态初始化块前,所以先输出Test--A
再换下位置,把static TestA ta = new TestA()放到在静态初始化块后,我们发现输出是:
静态变量
静态初始化块
Test--A
变量
初始化块
构造器
 
 
由此可见这是取决于它们在类中出现的先后顺序,同理可得:变量和初始化块之间也如此,总结可得:初始化优先级是(静态变量/静态初始化块)>(变量/初始化块)>构造器。
 
 
那继承关系时的初始化又是怎样的呢?如下:
大家应该知道,初始化子类时会先初始化父类,再看代码:
 
  1. public class Test extends Parent{ 
  2.     // 静态变量 
  3.     public static String staticField = "子类静态变量"; // 变量 
  4.     public String field = "子类变量"
  5.     // 静态初始化块 
  6.     static { 
  7.         System.out.println(staticField); 
  8.         System.out.println("子类静态初始化块"); 
  9.     } 
  10.     //public static TestA ta = new TestA(); 
  11.     // 初始化块 
  12.     { 
  13.         System.out.println(field); 
  14.         System.out.println("子类初始化块"); 
  15.     } 
  16.     // 构造器 
  17.     public Test() { 
  18.         System.out.println("子类构造器"); 
  19.     } 
  20.     public static void main(String[] args) { 
  21.         Test test = new Test(); 
  22.     } 
  23.  
  24. class Parent{ 
  25.  
  26.     public String field = "父类变量";// 变量 
  27.     public static String staticField = "父类静态变量"; // 静态变量 
  28.     // 静态初始化块 
  29.     static { 
  30.         System.out.println(staticField); 
  31.         System.out.println("父类静态初始化块"); 
  32.     } 
  33.     // 初始化块 
  34.     { 
  35.         System.out.println(field); 
  36.         System.out.println("父类初始化块"); 
  37.     } 
  38.     // 构造器 
  39.     public Parent() { 
  40.         System.out.println("父类构造器"); 
  41.     }    
刚才结果应该是:
父类静态变量
父类静态初始化块
子类静态变量
子类静态初始化块
父类变量
父类初始化块
父类构造器
子类变量
子类初始化块
子类构造器
 
从结果看到,并不是父类完全初始化完后再进行子类的初始化,子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
 
我们在main方法再创建一个对象,Test test2 = new Test();
大家就test2的初始化又如何?
 
为了好看,我们子类构造器里加多行代码System.out.println("***********");
输出结果:
父类静态变量
父类静态初始化块
子类静态变量
子类静态初始化块
父类变量
父类初始化块
父类构造器
子类变量
子类初始化块
子类构造器
***********
父类变量
父类初始化块
父类构造器
子类变量
子类初始化块
子类构造器
***********


发现什么了?
静态变量和静态代码块只加载一次 。
 
 
总结:
一、初始化优先级:
1、静态变量/静态初始化块)>(变量/初始化块)>构造器
2、父类>子类

二、静态变量和静态代码块只加载一次,因为它们是全局共享的
 
posted on 2012-07-28 12:45 tbwshc 阅读(907) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理