Java程序设计——初始化构造器加载顺序面试题

Posted on 2018-01-22 18:07  Jonathan_C  阅读(175)  评论(0)    收藏  举报

根据下面代码,分析输出的结果

 1 public class App {
 2     private static App d=new App();
 3     private Super_Class t=new Sub_Class();
 4     static {
 5         System.out.println('3');
 6     }
 7     public App(){
 8         System.out.println("4");
 9     }
10     public static void main(String[] args) {
11         System.out.println("Hello");
12     }
13 }
14 
15 class Super_Class{
16     Super_Class(){
17         System.out.println("构造superclass");
18     }
19 }
20 
21 class Sub_Class extends Super_Class{
22     static {
23         System.out.println("1");
24     } 
25     Sub_Class(){
26         System.out.println("2");
27     }
28 }

分析如下:

  • 首先看一遍全部代码,知道main主方法在App类中,App类内,有两个初始化工作:
1 private static App d=new App();//初始化一个对象,用静态static修饰
2 private Super_Class t=new Sub_Class();//初始化一个sub_Class对象t,继承于super_class
  • 那么首先要明白在App类中实现第二行初始化,依赖于sub_class和super_class类。所以根据这个首要原则,去找sub_class类,该类内有一个static静态代码块,所以JVM会先加载这个代码块,故先输出1
  • 同时,第二行的初始化,作为非static修饰,那么其工作是在构造器中完成的。类似于下面代码。
 1 public class App {
 2     private static App d=null;
 3     private Super_Class t=null;//t=null
 4     static {
       d= new App();//static修饰的,在static代码块内完成  
5 System.out.println('3'); 6 } 7 public App(){ t=new Sub_Class()//在构造期内,初始化操作 8 System.out.println("4"); 9 } 10 public static void main(String[] args) { 11 System.out.println("Hello"); 12 } 13 }
  • 所以,调用了sub_class,进入sub_class内有一个隐式的super()继承,故会先输出:构造superclass,之后再输出:2。
  • 在app构造器内,输出:4
  • 之后,静态方法static代码块内输出3
  • 最后, main入口输出hello。
  • 完毕!