Java⽗类⼦类的对象初始化过程
摘要
Java基本的对象初始化过程,⼦类的初始化,以及涉及到⽗类和⼦类的转化时可能引起混乱的情况。
1. 基本初始化过程:
对于⼀个简单类的初始化过程是:
static 修饰的模块(static变量和static 块)  ---> 按照代码顺序依次执⾏。
|
实例变量及⾮static模块---> 按照代码顺序依次执⾏。
|
构造函数 ---> 执⾏对应的构造函数。
⼦类的初始化过程。
⽗类static修饰的模块
|
static修饰的变量
⼦类static修饰模块
|
⽗类实例变量和⾮static块
|
⽗类对应构造函数。当⼦类对应构造函数中没有显⽰调⽤时调⽤的是⽗类默认的构造函数。
|
⼦类实例变量和⾮static块
|
⼦类构造函数
Class的static模块是唯⼀的,所以只初始化⼀次。所有类的实例公⽤Class的static模块。
static模块的初始化条件: ( From:引⽤1 )
(1)遇到new、getstatic、putstatic 或 invokestatic这4条字节码指令时,如果类还没初始化,则触发初始化。对应场景是:new实例化对象时、读或设置⼀个静态字段时(被final修饰,已在编译器把结果放⼊常量池的静态字段除外),以及调⽤⼀个类的静态⽅法时
(2)对类进⾏反射调⽤时
(3)初始化⼦类。但⽗类还没有初始化时,先触发⽗类初始化
(4)当虚拟机启动时,需指定⼀个需要执⾏的主类(包含main⽅法),虚拟机会先初始化该类
2. 关于覆盖和隐藏
覆盖:被覆盖的⽅法相当于被擦除了,不可恢复(即使类型强制转换也⽆法调⽤)。
隐藏:⼀直保存的某个位置,等需要的时候可以继续使⽤(类型强制转换后可以调⽤)。
关于⽗类⼦类之间的覆盖和隐藏关系:(From :引⽤2)
1. ⽗类的实例变量和类变量能被⼦类的同名变量隐藏。
2. ⽗类的静态⽅法被⼦类的同名静态⽅法隐藏,⽗类的实例⽅法被⼦类的同名实例⽅法覆盖。
3. 不能⽤⼦类的静态⽅法隐藏⽗类的实例⽅法,也不能⽤⼦类的实例⽅法覆盖⽗类的静态⽅法,否则编译器会异常。
4. ⽤final关键字修饰的最终⽅法不能被覆盖。
5. 变量只能被隐藏不会被覆盖,⼦类的实例变量可以隐藏⽗类的类变量,⼦类的类变量也可以隐藏⽗类的实例变量。
涉及的典型情况:
前提:
-----------------------------------------
class B extends A{……}
-----------------------------------------
(1) B instanceB = new B();
instanceB的初始化过程如第⼀部分中:⼦类的初始化过程。
此时instanceB中实际上有⼀个super的全部信息(除了⽗类中被覆盖的实例⽅法),但是当前的引⽤是⼦类的信息(如果⼦类中没有的变量和⽅法则是从⽗类继承来)。
(2)A instanceA = new B();
此时⽗类A的变量和静态⽅法会将⼦类的变量和静态⽅法隐藏。instanceA此时唯⼀可能调⽤的⼦类B的地⽅就是⼦类B中覆盖了⽗类A中的实例⽅法。
执⾏ B instanceB = (B) instanceA; 后
此时instanceB相当于 B instanceB = new B();
注意:
(1) 这⾥唯⼀的覆盖的情况:⽗类的实例⽅法被⼦类的同名实例⽅法覆盖。
这⾥⽅法调⽤变量时,实际上是带有⼀个默认的this的。也就是此实例⽅法中调⽤的是当前Class的值。
涉及到继承的情况时,要⼗分注意super,this的情况。
(2) 在初始化的时候,有两个阶段。第⼀步是申请空间,第⼆步是赋值。
具体见:
static的值和final static值在初始化时的区别。(引⽤1)
⼦类覆盖⽗类实例⽅法时,调⽤⼦类的实例⽅法,⽽此时⼦类的实例⽅法调⽤了⼦类中的变量(此时static变量已经初始化,但是实例变量并没有初始化)。(引⽤2)
这段代码来⾃引⽤2,如何精炼,如此有趣。值得⼀看。
class Parent{
int x=10;
public Parent(){
add(2);
}
void add(int y){
x+=y;
}
}
class Child extends Parent{
int x=9;
void add(int y){
x+=y;
}
public static void main(String[] args){
Parent p=new Child();
System.out.println(p.x);
}
}
引⽤ 1. 类加载机制:
引⽤ 2. 隐藏和覆盖,以及⼀个好例⼦:引⽤ 3. 隐藏和覆盖
引⽤ 4. 基本的初始化过程

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。