Java初始化顺序的验证(Cannot reference XXX before supertype constructor has been called引发的思考)
2016-07-18 11:49
806 查看
1、问题的发现
最近在进行数据库方面的编码时,无意间发现了一个报错信息,“Cannot reference XXX before supertype constructor has been called”。意思很明显,在父类构函数初始化之前不能引用这个变量。当把这个变量加上startic修饰符时,就不再报错。2、猜想验证
那么为什么加上static修饰后,就不再报错了呢?很显然,与Java的初始化顺序有关。因此,Coder哥编写了一个验证Java初始化顺序的验证代码/** * 父类 */ public class Base { static String sVar = getString("父类静态变量初始化"); public String var = getString("父类非静态变量初始化"); static { System.out.println("父类的静态初始化块"); } { System.out.println("父类的非静态初始化块"); } public Base() { System.out.println("父类构造函数 start"); draw("父类调用draw方法");//会调用子类覆盖后的方法,这里是null System.out.println("父类构造函数 end"); } static String getString(String base) { System.out.println(base); return base; } public void draw(String string) { System.out.println(string); } }
/** * 子类 */ public class SubClass extends Base { public String var = getString("子类初始化非静态变量"); private String subVar = getString("子类初始化私有变量"); static String superVar = getString("子类初始化静态变量"); static { System.out.println("子类的静态初始化块"); } { System.out.println("子类的非静态初始化块"); } SubClass() { System.out.println("子类构造函数start"); draw("子类调用draw方法"); System.out.println("子类构造函数end"); } public void draw(String string) { System.out.println(string + subVar); } public static void main(String[] args) { new SubClass(); } }
运行程序后,得到的结果如下:
父类静态变量初始化 父类的静态初始化块 子类初始化静态变量 子类的静态初始化块 父类非静态变量初始化 父类的非静态初始化块 父类构造函数 start 父类调用draw方法 null 父类构造函数 end 子类初始化非静态变量 子类初始化私有变量 子类的非静态初始化块 子类构造函数 start 子类调用draw方法子类初始化私有变量 子类构造函数 end
3、结果分析
由此结果,我们便可以清楚的看出文章开头那个错误的原因:父类构造函数初始化早于子类非静态变量的初始化,晚于子类静态变量的初始化。所以,当我们把变量改为静态修饰时,不会再报错了。大家可以自己动手亲自试验一下Java的初始化过程,在以后的编程中会有很大的用处。相关文章推荐
- css引入错误的解决办法
- Javascript-网页编程-DHTML-复选框加强
- HTML适配 css代码根据屏幕大小适配 导入自己想要的字体
- CSS图像替换:文本缩进,负边距以及更多方法
- [javascript权威指南][阅读笔记]七
- 浅析JavaScript中的array数组类型系统
- [javascript权威指南][阅读笔记]六
- CSS定位布局
- CSS布局模型
- jQuery——获取并设置CSS类
- 总结JavaScript事件机制
- HTML标签元素的分类
- css垂直居中的方法
- HTML文字与段落
- Java与React Native之间传递参数
- 详解JS类概念的实现
- javascript Windows对象(BOM)
- javascript DOM对象
- Newtonsoft.Json高级用法
- eglMakeCurrent, eglSwapBuffers, glFlush, glFinish