几个问题(--------)父子类静态变量、静态代码块、非静态代码块、构造函数

来源:互联网 发布:淘宝店怎么做优惠卷 编辑:程序博客网 时间:2024/06/01 07:36
 
Java代码
  1. class Parent{     
  2.     static String name = "hello";     
  3.     static {     
  4.         System.out.println("parent static block");     
  5.     }   
  6.     {   
  7.         System.out.println("parent block");    
  8.     }   
  9.     public Parent(){     
  10.         System.out.println("parent constructor");     
  11.     }     
  12. }     
  13.      
  14. class Child extends Parent{     
  15.     static String childName = "hello";     
  16.     static {     
  17.         System.out.println("child static block");     
  18.     }   
  19.     {   
  20.         System.out.println("child block");    
  21.     }     
  22.     public Child(){     
  23.         System.out.println("child constructor");     
  24.     }     
  25. }     
  26.      
  27. public class StaticIniBlockOrderTest {     
  28.      
  29.     public static void main(String[] args) {     
  30.         new Child();//语句(*)     
  31.     }     
  32. }   
问题:当执行完语句(*)时,打印结果是什么顺序?为什么?
解答:当执行完语句(*)时,打印结果是这样一个顺序:parent static block,child static block,parent  block,parent constructor,child  block,child constructor。
分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。

总结:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
父类Static->子类static->父类缺省{}->父类构造函数->子类缺省{}->子类构造函数
(静态变量、静态初始化块)>(变量、初始化块)>构造器
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
 
Java代码
  1. class Parent {   
  2.     // 静态变量   
  3.     public static String p_StaticField = "父类--静态变量";   
  4.     // 变量   
  5.     public String p_Field = "父类--变量";   
  6.   
  7.     // 静态初始化块   
  8.     static {   
  9.         System.out.println(p_StaticField);   
  10.         System.out.println("父类--静态初始化块");   
  11.     }   
  12.   
  13.     // 初始化块   
  14.     {   
  15.         System.out.println(p_Field);   
  16.         System.out.println("父类--初始化块");   
  17.     }   
  18.   
  19.     // 构造器   
  20.     public Parent() {   
  21.         System.out.println("父类--构造器");   
  22.     }   
  23. }   
  24.   
  25. public class SubClass extends Parent {   
  26.     // 静态变量   
  27.     public static String s_StaticField = "子类--静态变量";   
  28.     // 变量   
  29.     public String s_Field = "子类--变量";   
  30.     // 静态初始化块   
  31.     static {   
  32.         System.out.println(s_StaticField);   
  33.         System.out.println("子类--静态初始化块");   
  34.     }   
  35.     // 初始化块   
  36.     {   
  37.         System.out.println(s_Field);   
  38.         System.out.println("子类--初始化块");   
  39.     }   
  40.   
  41.     // 构造器   
  42.     public SubClass() {   
  43.         System.out.println("子类--构造器");   
  44.     }   
  45.   
  46.     // 程序入口   
  47.     public static void main(String[] args) {   
  48.         new SubClass();   
  49.     }   
  50. }  

运行一下上面的代码,结果马上呈现在我们的眼前:
  1. 父类--静态变量
  2. 父类--静态初始化块
  3. 子类--静态变量
  4. 子类--静态初始化块
  5. 父类--变量
  6. 父类--初始化块
  7. 父类--构造器
  8. 子类--变量
  9. 子类--初始化块
  10. 子类--构造器
 
可是静态代码块真的会一定在非静态代码块之前执行吗?
Java代码
  1. public class ExA {   
  2.     private static ExA a = new ExA();   
  3.     static {   
  4.         System.out.println("父类--静态代码块");   
  5.     }   
  6.   
  7.     public ExA() {   
  8.         System.out.println("父类--构造函数");   
  9.     }   
  10.   
  11.     {   
  12.         System.out.println("父类--非静态代码块");   
  13.     }   
  14.   
  15.     public static void main(String[] args) {   
  16.         new ExB();   
  17.     }   
  18. }   
  19.   
  20. class ExB extends ExA {   
  21.     private static ExB b = new ExB();   
  22.     static {   
  23.         System.out.println("子类--静态代码块");   
  24.     }   
  25.     {   
  26.         System.out.println("子类--非静态代码块");   
  27.     }   
  28.   
  29.     public ExB() {   
  30.         System.out.println("子类--构造函数");   
  31.     }   
  32. }  

执行结果
=====
父类--非静态代码块
父类--构造函数
父类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数
子类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数
=====
可以发现非静态代码块并不是一定在静态代码块之后执行的。
我认为此时private static ExA a = new ExA()是静态变量。而java里面静态变量与静态代码块是按代码先后顺序执行。所以就导致非静态代码块在静态代码块之前执行。
 
 
原创粉丝点击