博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java基础】父类与子类中各成员初始化顺序
阅读量:4113 次
发布时间:2019-05-25

本文共 2575 字,大约阅读时间需要 8 分钟。

java中子类与父类的初始化顺序每次遇到都会想一想,尤其是遇到复杂的子类与父类中多态和方法重载交织在一起的时候,但是总结一下,还是那个特定的规律。

看个例子吧。

class Egg{	static{		System.out.println("父类静态代码块初始化");	}    private int  a = 1;    {    	System.out.println("父类代码块初始化" + a + "  b=1证明成员变量已经初始化了");    }        public Egg(){        System.out.println("父类构造函数初始化");    }}class BigEgg extends Egg{	static{		System.out.println("子类静态代码块初始化");	}	private int  b = 2;    {    	System.out.println("子类代码块初始化 " + b + "  b=2证明成员变量已经初始化了");    }    public BigEgg(){        System.out.println("子类构造函数初始化");    }}public class TestClassInitSeq{	 public static void main(String[] args){	        new BigEgg();	 }}
输出结果:

父类静态代码块初始化

子类静态代码块初始化
父类代码块初始化1  b=1证明成员变量已经初始化了
父类构造函数初始化
子类代码块初始化 2  b=2证明成员变量已经初始化了
子类构造函数初始化
从输出结果可以看出这样的初始化顺序:

① 如果类中存在继承关系,则首先会初始化基类(Egg),然后再是子类(BigEgg);

② 在基类中首先会初始化静态的东西,静态代码块和静态变量(类变量),谁在前就先初始化谁,静态的东西是跟着类的加载而加载的;

③ 然后是初始化子类静态的东西,静态代码块和静态变量,跟父类中的顺序相同,还是谁在前先初始化谁;

④ 接着是父类代码块和成员变量,同样也是谁在前谁先初始化;

⑤ 初始化父类的构造函数(调用有参就初始化有参构造器);

⑥ 接着初始化子类的代码块和成员变量,谁在前谁先初始化;

⑦ 初始化子类的构造函数(调用有参就初始化有参构造器)。

举个例子再来说明和验证一下:

class Father0{	   private static String str = "静态变量初始化";   static{          System.out.println("父类静态代码块初始化" );          System.out.println(str);   }      {          System.out.println("父类代码块初始化" );   }      private static String s= print();   public static String print()   {          System.out.println("父类静态方法" );          return "父类静态成员变量的初始化" ;   }   public Father0()   {          System.out.println("父类无参构造函数初始化完成" );          show();   }   public void show()   {          System.out.println("父类show()方法" );   }}class Son extends Father0{   static{          System.out.println("子类静态代码块初始化" );   }   {          System.out.println("子类代码块初始化" );   }   private int i =1;   private String s="子类私有成员变量" ;      public Son()   {          System.out.println("子类构造函数初始化完成" );          System.out.println("子类成员变量初始化完成:s=" +s);          show();   }   public void show()   {          System.out.println("子类show()方法:i=" +i);   }}public class TestClassLoadSeq {    public static void main(String[] args){           new Son();   }}

输出结果:

父类静态代码块初始化

静态变量初始化
父类静态方法
子类静态代码块初始化
父类代码块初始化
父类无参构造函数初始化完成
子类show()方法:i=0
子类代码块初始化
子类构造函数初始化完成
子类成员变量初始化完成:s=子类私有成员变量
子类show()方法:i=1

从输出结果看,顺序完全是按照上面总结的那个顺序。不同的是父类中有了两个静态变量,而且父类中第二个静态变量指向一个静态方法,所以才有了父类静态方法的初始化。

父类构造函数中调用了一个show()方法,由于是new 子类的实例,所以执行的是子类的show()方法,但是子类的成员变量在父类构造函数执行时还没有初始化,所以此时i=0,当子类中构造函数执行时,调用show()方法,此时成员变量已经初始化了输出i=1。

实际上,本文讨论的都是真正执行的顺序,没有站在JVM的类加载的立场,JVM加载类时做了很多初始化动作,会对每个基本数据类型初始化为各个基本数据类型的0,比如int型会初始化为0,boolean型初始化为false,组合引用类型初始化为null等等

反正,这些基础知识对后面学习还是有一定帮助的,不会让你每次遇到时都要犹豫和徘徊一下。

如有错误望指正。

转载地址:http://tuwpi.baihongyu.com/

你可能感兴趣的文章
vue2.* 中 使用socket.io
查看>>
openlayers安装引用
查看>>
js报错显示subString/subStr is not a function
查看>>
高德地图js API实现鼠标悬浮于点标记时弹出信息窗体显示详情,点击点标记放大地图操作
查看>>
初始化VUE项目报错
查看>>
vue项目使用安装sass
查看>>
HTTP和HttpServletRequest 要点
查看>>
在osg场景中使用GLSL语言——一个例子
查看>>
关于无线PCB中 中50欧姆的特性阻抗的注意事项
查看>>
Spring的单例模式源码小窥
查看>>
后台服务的变慢排查思路(轻量级应用服务器中测试)
查看>>
MySQL中InnoDB事务的默认隔离级别测试
查看>>
微服务的注册与发现
查看>>
bash: service: command not found
查看>>
linux Crontab 使用 --定时任务
查看>>
shell编程----目录操作(文件夹)
查看>>
机器学习-----K近邻算法
查看>>
HBASE安装和简单测试
查看>>
关于程序员的59条搞笑但却真实无比的编程语录
查看>>
tomcat 使用心得(问题)-eclipse 启动tomcat 后 浏览器访问404 --eclipse复制工程显示原来的工程名
查看>>