Java基类和派生类中方法的执行顺序

这篇文章主要介绍了Java基类和派生类中各种方法的加载顺序(常见于面试题),本文直接给出代码实例和运行结果,给后给出了加载过程总结,需要的朋友可以参考下。

先放结论,总结如下:

1. 构造类的实例对象前,先加载类本身。

2.若要加载类A,则先加载执行其父类B)的静态变量以及静态语句块(执行先后顺序按排列的先后顺序)。
然后再加载执行类A的静态变量以及静态语句块。(并且对于所有的A的对象,加载A(及B)只会执行1次)

3.若需实例化类A,则先调用其父类B的构造函数,并且在调用其父类B的构造函数前,依次先调用父类B中的非静态变量及非静态语句块.最后再调用父类B中的构造函数初始化。然后再依次调用类A中的非静态变量及非静态语句块,最后调用A中的构造函数初始化。

4.而对于静态方法和非静态方法都是被动调用,即系统不会自动调用执行,所以用户没有调用时都不执行,主要区别在于静态方法可以直接用类名直接调用(实例化对象也可以),而非静态方法只能先实例化对象后才能调用。

基类静态语句块->派生类静态语句块->(若两个类都未被加载过,这个过程有且只有一次)

基类非静态语句块-基类构造函数->派生类非静态语句块->派生类构造函数->(每次构造都会出现

被调用的(静态、非静态)方法。

追问:
先有父亲后有儿子,这句话不是只针对“构建对象”而言的吗,他也针对“类的加载”吗?我的理解是:对于构建对象的话,
的确是应该先构建父类对象,才能构建子类对象。但对于类的加载的话
,不应该是看到内存中缺少了哪个类就应该加载哪个类的吗?
追答:
加载的时候也是一样的,当加载类A的时候,发现有父类B,就去搜索并加载B了,
这个时候还没有加载A中那些静态块,等B加载完了之后,才会返回来加载A,
也只有这样,程序才知道A中到底会有些什么方法,因为A中存在着由B继承而来的方法。
如果先加载了A,那么就会出现两种情况,一种是A中没有继承而来的方法,
另一种是加载B后再一次加载A继承而来的方法,那这样的Java就太差劲了,你说呢?

测试代码和结果:

[java]  view plain  copy
  1.   
[java]  view plain  copy
  1. package com.company;  
  2.   
  3. public class Main{  
  4.     public static void main(String[] args){  
  5.         A a1 = new A();  
  6.         System.out.println("End of test a1 ");  
  7.         A a2 = new A();  
  8.         //a.aDisplay();  
  9.         System.out.println("End of test a2");  
  10.     }  
  11. }  
  12. class B{  
  13.     //静态变量  
  14.     static int i = 1;  
  15.     //非静态变量  
  16.     int j = 1;  
  17.     //静态语句块  
  18.     static {  
  19.         System.out.println("Base Class B:static blocks i = " + i);  
  20.     }  
  21.     //构造函数  
  22.     public B(){  
  23.         i++;  
  24.         j++;  
  25.         System.out.println("Base constructor B: "+" i = " + i + ", j = " + j);  
  26.     }  
  27.     //非静态语句块  
  28.     {  
  29.         i++;  
  30.         j++;  
  31.         System.out.println("Base Class B:non-static blocks " + "i = " + i + ", j = " + j);  
  32.     }  
  33.     //非静态方法  
  34.     public void bDisplay(){  
  35.         i++;  
  36.         System.out.println("Base Class B:static void bDisplay():    " + " i = " + i + " , j = "+j);  
  37.         return ;  
  38.     }  
  39.     //静态方法  
  40.     public static void bTest(){  
  41.         i++;  
  42.         System.out.println("Base Class B:static void bTest():   " + " i = " + i);  
  43.         return ;  
  44.     }  
  45. }  
  46.   
  47. class A extends B{  
  48.     //静态变量  
  49.     static int i = 1;  
  50.     //非静态变量  
  51.     int j = 1;  
  52.     //静态语句块1  
  53.     static {  
  54.         System.out.println("Derived Class A:static blocks i = " + i);  
  55.     }  
  56.     //构造函数  
  57.     public A(){  
  58.         super();  
  59.         i++;  
  60.         j++;  
  61.         System.out.println("Derived constructor A: " + " i = " + i + " , j = " + j);  
  62.     }  
  63.     //静态语句块2  
  64.     static{  
  65.         i++;  
  66.         System.out.println("Derived Class A:static blocks i = " + i);  
  67.     }  
  68.     //非静态语句块  
  69.     {  
  70.         i++;  
  71.         j++;  
  72.         System.out.println("Derived Class A:non-static blocks" + " i = " + i + " , j = " + j);  
  73.     }  
  74.     //非静态方法  
  75.     public void aDisplay(){  
  76.         i++;  
  77.         System.out.println("Derived Class A:static void aDisplay(): "+" i = " + i + " , j = " + j);  
  78.         return ;  
  79.     }  
  80.     //静态方法  
  81.     public static void aTest(){  
  82.         i++;  
  83.         System.out.println("Derived Class A:static void aTest(): " + " i = " + i);  
  84.         return ;  
  85.     }  
  86. }  

执行结果如下:(运行环境IntelliJ IDEA + jdk 1.8)

[java]  view plain  copy
  1. /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/bin/java...  
  2. Base Class B:static blocks i = 1  
  3. Derived Class A:static blocks i = 1  
  4. Derived Class A:static blocks i = 2  
  5. Base Class B:non-static blocks i = 2, j = 2  
  6. Base constructor B:  i = 3, j = 3  
  7. Derived Class A:non-static blocks i = 3 , j = 2  
  8. Derived constructor A:  i = 4 , j = 3  
  9. End of test a1   
  10. Base Class B:non-static blocks i = 4, j = 2  
  11. Base constructor B:  i = 5, j = 3  
  12. Derived Class A:non-static blocks i = 5 , j = 2  
  13. Derived constructor A:  i = 6 , j = 3  
  14. End of test a2  
  15.   
  16. Process finished with exit code 0  

猜你喜欢

转载自blog.csdn.net/qq_36838191/article/details/80275873
今日推荐