JAVA面试题解惑系列(一)——类的初始化顺序

来源:互联网 发布:协方差矩阵例子 编辑:程序博客网 时间:2024/05/16 15:03
原文地址:http://zangweiren.javaeye.com/blog/208122

作者:臧圩人 
网址:http://zangweiren.javaeye.com 

大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我们对于继承情况下类的初始化顺序的了解。 

我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点: 
Java代码 
public class InitialOrderTest {  
  
  // 静态变量  
  public static String staticField = "静态变量";  
  // 变量  
  public String field = "变量";  
  
  // 静态初始化块  
  static {  
  System.out.println(staticField);  
  System.out.println("静态初始化块");  
  }  
  
  // 初始化块  
  {  
  System.out.println(field);  
  System.out.println("初始化块");  
  }  
  
  // 构造器  
  public InitialOrderTest() {  
  System.out.println("构造器");  
  }  
  
  public static void main(String[] args) {  
  new InitialOrderTest();  
  }  
}  

运行以上代码,我们会得到如下的输出结果: 

静态变量 
静态初始化块 
变量 
初始化块 
构造器 

这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果: 
Java代码 
class Parent {  
  // 静态变量  
  public static String p_StaticField = "父类--静态变量";  
  // 变量  
  public String p_Field = "父类--变量";  
  
  // 静态初始化块  
  static {  
  System.out.println(p_StaticField);  
  System.out.println("父类--静态初始化块");  
  }  
  
  // 初始化块  
  {  
  System.out.println(p_Field);  
  System.out.println("父类--初始化块");  
  }  
  
  // 构造器  
  public Parent() {  
  System.out.println("父类--构造器");  
  }  
}  
  
public class SubClass extends Parent {  
  // 静态变量  
  public static String s_StaticField = "子类--静态变量";  
  // 变量  
  public String s_Field = "子类--变量";  
  // 静态初始化块  
  static {  
  System.out.println(s_StaticField);  
  System.out.println("子类--静态初始化块");  
  }  
  // 初始化块  
  {  
  System.out.println(s_Field);  
  System.out.println("子类--初始化块");  
  }  
  
  // 构造器  
  public SubClass() {  
  System.out.println("子类--构造器");  
  }  
  
  // 程序入口  
  public static void main(String[] args) {  
  new SubClass();  
  }  
}  

运行一下上面的代码,结果马上呈现在我们的眼前: 

父类--静态变量 
父类--静态初始化块 
子类--静态变量 
子类--静态初始化块 
父类--变量 
父类--初始化块 
父类--构造器 
子类--变量 
子类--初始化块 
子类--构造器 

现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。 

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。 

同样,我们还是写一个类来进行测试: 
Java代码 
public class TestOrder {  
  // 静态变量  
  public static TestA a = new TestA();  
   
  // 静态初始化块  
  static {  
  System.out.println("静态初始化块");  
  }  
   
  // 静态变量  
  public static TestB b = new TestB();  
  
  public static void main(String[] args) {  
  new TestOrder();  
  }  
}  
  
class TestA {  
  public TestA() {  
  System.out.println("Test--A");  
  }  
}  
  
class TestB {  
  public TestB() {  
  System.out.println("Test--B");  
  }  
}  

运行上面的代码,会得到如下的结果: 

Test--A 
静态初始化块 
Test--B 

大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。 

了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 年轻嫂嫂5完整中文字幕版 漂亮伯母到我家来住宿电影 年轻的岳毋2018中文 年轻的婶子在线播放1080p 中文全彩再伯母家大汗淋漓电影 我和二伯母愉情电子书 与邻居我和邻居阿夷愉情 我和农村留守妇女愉情真实故事 西游记 之三插王母 水原梨花母友人中文字幕 屁孩睡走叔母3中文字幕 林氏集团和伯母 太监跟娘娘私通小说 欧阳锋跟他大嫂私通在哪一集 太监跟娘娘私通 我和唐伯母在厨房 同居了大嫂中文字幕 年轻的后妈1完整高清免费观看 漂亮的老婆在线中字幕 母亲今晚让你入个够免费阅读 漂亮的续母韩国电影 我的漂亮后妈201电影 朋友的母亲3字幕中文翻译 邻居喝醉我睡了他老婆 白天当儿子晚上当丈夫视频 二姑装睡让我 白天是儿子晚上是丈夫阅读 老公去世和儿儿子做 白天是我妈晚上是老婆 蜜母耻中文字幕下载 友人之母中文字幕视频 友人之母增尾彩 内田春菊友人之母 母友人佐佐木明希中文字幕 友人之母谷源希美西瓜 母友人三浦中文字幕在线播放 大嫂被逼无奈和小叔传种接代 母友人作品封面 6公公与儿熄中文字幕完整视频 退休闲负的公公在家要了我5 我妻子的母亲hd高清中文字幕