Java中父类与子类的加载顺序详解

最近准备换工作,好久没笔试面试的我,就网上找了点大家分享的题随便看了看。然后就看到有关于Java中父类与子类的加载顺序的题,出简单点的就出选择题,出复杂的就出成简答题了。说句实话,在实际开发工作中,好像用不到(也许是我技术不到家,所以没用到吧)但是为了应付笔试还是得了解。开始正题吧。

1、在没有子类的情况下

package lcy;

public class Test6 {

 /** 
  * 方法描述:移动端—
  * 创建人:汪俊 
  * 创建时间:2017-8-1 上午09:01:37 
  * 修改人:汪俊 
  * 修改时间:2017-8-1 上午09:01:37 
  * 修改备注: 
  * @version V1.0 
  */
  //静态变量 
  static String i=lcy();
  public static String lcy()
  {
   System.out.println("父类静态变量");
   return "静态变量";
  }	
  //静态语句块
  static {
      System.out.println("父类静态语句块1");
  }
  //静态语句块
  static {
      System.out.println("父类静态语句块2");
  }
  //静态语句块
  static{
      System.out.println("父类静态语句块3");
  }
  
  //非静态变量 
  String j=pplcy();
  public String pplcy()
  {
   System.out.println("父类非静态变量");
   return "父类非静态变量";
  }	
  //非静态语句块
  {
    System.out.println("父类非静态语句块1");
  }
  //非静态语句块
  {
    System.out.println("父类非静态语句块2");
  }
  //非静态方法
  public void bDisplay(){
      System.out.println("父类非静态方法");
      return ;
  }
  //静态方法
  public static void bTest(){
      System.out.println("父类静态方法");
      return ;
  }
  //构造函数
  public Test6(){
      System.out.println("父类构造函数");
  }

  
  public static void main (String args[]) {
   Test6 a=new Test6();
   a.bDisplay();
   a.bTest();
   
     }
}
运行结果分析①
父类静态变量
父类静态语句块1
父类静态语句块2
父类静态语句块3
父类非静态变量
父类非静态语句块1
父类非静态语句块2
父类构造函数
父类非静态方法
父类静态方法
结论:在初始化类时候,首先加载类的静态变量和静态语句块(按照代码上下顺序执行),然后加载类的非静态变量和非静态语句块(按照代码上下顺序执行),最后加载类的构造函数。
至于类的静态方法和非静态方法只有主动调用的时候才会执行,区别在于静态方法可以直接用类名直接调用(实例化对象也可以),而非静态方法只能先实例化对象后才能调用。
2、在有子类的情况下
package lcy;

public class Test7 extends Test6 {

 /** 
  * 方法描述:移动端—
  * 创建人:汪俊 
  * 创建时间:2017-8-1 上午09:01:37 
  * 修改人:汪俊 
  * 修改时间:2017-8-1 上午09:01:37 
  * 修改备注: 
  * @version V1.0 
  */
  //静态变量 
  static String a=lcyhh();
  public static String lcyhh()
  {
   System.out.println("子类静态变量");
   return "静态变量";
  }	
  //静态语句块
  static {
      System.out.println("子类静态语句块1");
  }
  //静态语句块
  static {
      System.out.println("子类静态语句块2");
  }
  //静态语句块
  static{
      System.out.println("子类静态语句块3");
  }
  
  //非静态变量 
  String b=ppplcy();
  public String ppplcy()
  {
   System.out.println("子类非静态变量");
   return "子类非静态变量";
  }	
  //非静态语句块
  {
    System.out.println("子类非静态语句块1");
  }
  //非静态语句块
  {
    System.out.println("子类非静态语句块2");
  }
  //非静态方法
  public void bDisplay(){
      System.out.println("子类非静态方法");
      return ;
  }
  //静态方法
  public static void bTest(){
      System.out.println("子类静态方法");
      return ;
  }
  //构造函数
  public Test7(){
      System.out.println("子类构造函数");
  }
  
}
运行结果分析②:
Test6 a=new Test6(); //在父类Test6中执行结果,和 运行结果分析①完全相同
Test6 a=new Test6(); //在子类Test7中执行结果如下
父类静态变量
父类静态语句块1
父类静态语句块2
父类静态语句块3
子类静态变量
子类静态语句块1
子类静态语句块2
子类静态语句块3
父类非静态变量
父类非静态语句块1
父类非静态语句块2
父类构造函数
结论:在初始化父类Test6的时候,首先加载父类的静态变量和静态语句块(按照代码上下顺序执行),然后加载子类的静态变量和静态语句块(按照代码上下顺序执行),然后加载父类的非静态变量和非静态语句块(按照代码上下顺序执行),最后加载父类的构造函数。
运行结果分析③:
Test7 a=new Test7(); //在父类Test6和子类Test7中执行结果相同,如下
父类静态变量
父类静态语句块1
父类静态语句块2
父类静态语句块3
子类静态变量
子类静态语句块1
子类静态语句块2
子类静态语句块3
父类非静态变量
父类非静态语句块1
父类非静态语句块2
父类构造函数
子类非静态变量
子类非静态语句块1
子类非静态语句块2
子类构造函数
结论:在初始化子类Test7的时候,首先加载父类的静态变量和静态语句块(按照代码上下顺序执行),然后加载子类的静态变量和静态语句块(按照代码上下顺序执行),然后加载父类的非静态变量和非静态语句块(按照代码上下顺序执行),再加载父类的构造函数。然后加载子类的非静态变量和非静态语句块(按照代码上下顺序执行),最后加载子类的构造函数。

PS:不管是父类还是子类加载( 静态变量和静态语句块 )都只能加载一次。
不管是父类还是子类加载(静态变量和非静态语句块和构造函数 )都可重复加载。






©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页