原博文在:
JVM--从JVM层面深入解析对象实例化、多态性实现机制 (https://blog.csdn.net/championhengyi/article/details/78998821)
原文作者:珩翊
一. 虽然看不懂字节码及栈分析,但至少理解到了两点
1. this相当于指针变量,只读指针
2. 对象实例化次序(可能是):
2.1 this对象分配内存: 父类和当前类成员变量获得内存, 父类方法加载,当前类方法加载,this变量赋值
2.2 如果有静态成员: 父类静态成员变量初始化,父类静态方法可能被调用,
当前类静态成员变量初始化, 当前类静态方法可能被调用
2.3 继承自父类的成员变量初始化,调用继承自父类的构造方法,当前类的成员变量初始化,调用当前类的构造方法
3. 由于成员方法是所有对象"公用"的, 所以每个对象的内存中, 应该只保存了成员方法的入口地址(方法指针)
以下代码引自前述博文
public class SuperClass {
private int mSuperX;
public SuperClass() {
setX(99);
}
public void setX(int x) {
mSuperX = x;
}
}
public class SubClass extends SuperClass {
private int mSubX = 1;
public SubClass() {}
@Override
public void setX(int x) {
super.setX(x);
mSubX = x;
System.out.println("mSubX is assigned " + x);
}
public void printX() {
System.out.println("mSubX = " + mSubX);
}
}
最后在main里调用:
public class Main {
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.printX();
}
}
答案是这样的:
SubX is assigned 99
SubX = 1
二. 关于多态的理解
JVM--详解虚拟机字节码执行引擎之静态链接、动态链接与分派
https://blog.csdn.net/championhengyi/article/details/78760590
示例代码引自上述博文, 略有改动
1. 对象的静态类型与实际类型
对象变量声明语句 定义的变量类型是其 "静态类型" (有可能是父类 ), 在被强制向上转型时的类型也是静态类型
实际类型是由"构造函数"来决定的
例如 superClass objVar=new subClass()
objvar 的 静态类型 是superClass, 实际类型是 subClass
2. 在重载函数调用时, objvar作为实参被传入函数, 使用的是静态类型, 也就是变量声明时的类型
class Human {
}
class Man extends Human {
}
class Woman extends Human {
}
public class StaticDispatch {
public void sayHello(Human guy) {
System.out.println("hello, guy!");
}
// public void sayHello(Man guy){
// System.out.println("hello, gentleman!");
// }
public void sayHello(Woman guy){
System.out.println("hello, lady!");
}
public static void main(String[] args){
Man man = new Man(); //静态类型与实际类型一致
Human woman = new Woman(); //静态类型是Human, 实际类型是Woman
StaticDispatch sr = new StaticDispatch();
sr.sayHello(man); //man对象的静态类型是Man, 在调用函数时, 被向上转型为Human
sr.sayHello(woman); //woman对象的静态类型是Human
}
}
3. 在以对象名来调用其成员函数时, 会使用其实际类型
一个猜测: 如果父类方法被覆盖(Override 撤销/推翻), 则在当前类对象实例化时, 不会加载父类的同名方法
class Father {
public void doSomething() {
System.out.println("爸爸在吃饭" );
}
}
class Child extends Father {
public void doSomething( ) {
System.out.println("儿子在吃饭" );
}
}
public class SingleDoublePai {
public static void main(String[] args) {
Father father = new Father();
Father child = new Child(); //静态类型是Father, 实际类型是Child
father.doSomething();
child.doSomething();
}
}
爸爸在吃饭
儿子在吃饭