Java初始化非静态成员的时机
来源:互联网 发布:mac os 恢复 编辑:程序博客网 时间:2024/06/05 23:39
参考:http://blog.csdn.net/haoel/article/details/4319793
今天看到这篇文章吓了一跳,因为之前看过《Effective C++》,C++在构造函数里调用虚函数的结果是绝对不会将函数下降到子类去执行,即结果不可预测。那java呢?假设我告诉你一个事实:
Java支持在构造函数里调用虚函数
也就是说,在下面的代码中,调用Base()时,会调用Derived::preProcess(),那么最后的输出结果是什么呢?
package com.happyjacket.study;class Base{ public Base() { System.out.println("construct Base()"); preProcess(); } public void preProcess() { System.out.println("pre process in Base"); }}class Member{ public Member(String name) { System.out.println("construct Member " + name); }}class Derived extends Base { public String hello = "hello"; public Member member = new Member("jacket"); public Derived() { // 默认会在一开始调用super(); System.out.println("construct Derived() " + hello); hello = "initialized in Derived"; } public void preProcess() { System.out.println("pre process in Derived"); hello = "modified in Derived..."; }}public class Main { public static void main(String[] args) { Derived child = new Derived(); System.out.println(child.hello); }}
我一开始也以为是这样的(注意第4行):
construct Base()pre process in Derivedconstruct Member jacketconstruct Derived() modified in Derived...initialized in Derived
!!!但运行结果却是:
construct Base()pre process in Derivedconstruct Member jacketconstruct Derived() helloinitialized in Derived
注意第4行!!!以及第3行是在第4行前面的,说明什么呢?
就是非静态成员的初始化时机了,它是发生于调用super()之后(不考虑自行调用super()的情况)而自定义的实体之前的时候。
也就是说,整个流程是这样的:
1. 执行Derived(),会先执行编译器加入的super();
2. 执行Base(),打印第一行;
3. 在Base()里调用preProcess(),执行的是Derived::preProcess(),它打印第二行并将hello的值设置为”modified in Derived…”,Base()调用结束;
4. 回到Derived(),先按成员的声明顺序对各个成员进行初始化,hello的值被设置为”hello”;
5. 执行Derived()自定义的函数体,打印第4行,注意此时hello的值;
6. 最后hello的值被设置为”initialized in Derived”,回到主函数,打印出第5行。
总结一下:
1. Java支持在构造函数里调用(子类相应的)虚函数(其实我觉得挺奇怪的,因为感觉只是重写父类的函数而已,就是虚函数了吗?java里的虚函数就是override吗?)
2. 非静态成员的初始化时机不是在声明的时候,而是在super()执行之后,而执行构造函数自定义的实体之前。
- Java初始化非静态成员的时机
- Java静态变量初始化时机
- Java 静态变量、静态代码块初始化的时机
- 静态变量初始化的时机
- java 继承时子类父类的静态非静态成员变量,构造方法,静态代码块的初始化顺序
- java类的加载 初始化时机,已经静态代码块的执行时机
- 静态成员的初始化顺序(C#,java)
- static final成员变量的初始化时机
- final修饰的成员变量初始化时机
- 声明为非成员函数的时机
- 类中的静态成员变量 非静态成员变量的初始化问题
- 关于静态变量的初始化时机
- java类的初始化时机
- java 类初始化的时机
- Java静态成员初始化问题
- java基础,静态变量,静态初始化块,初始化快,成员变量的初始化顺序
- java静态变量和非静态变量的初始化
- 静态变量、实例变量初始化时机,以及子类隐藏父类成员时,创建子类对象的一些问题
- UVA 10200 Prime Time (打表)(精度太坑了)
- codeforces 589J
- BZOJ 3668 [Noi2014]起床困难综合症
- Android 点击View Rotate旋转带属性动画
- 深入分析C++引用
- Java初始化非静态成员的时机
- LeetCode: Duplicate Emails
- Java可变参数方法
- 人物角色对象的一级基址
- linux上给php安装mysqli扩展
- kuangbin求带飞DP1 Common Subsequence(LCS)
- fzu1686神龙的难题(Dancing Links(重复覆盖))
- BZOJ 1012 [JSOI2008]最大数maxnumber
- RxBus学习之旅--从入门到提高