JAVA对象的实例化过程与多态的理解

原博文在:

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 {  
    public void sayYes() {  
        System.out.println("Yes, Human!");  
    }  
}

class Man extends Human {  
    public void sayYes() {  
        System.out.println("Yes, Man!");  
    }  
	
}  

class Woman extends Human {  
    public void sayYes() {  
        System.out.println("Yes, Woman!");  
    }  
}  

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

        man.sayYes();        
        woman.sayYes();      //通过对象名调用函数, 使用的是实际类型的函数

    }  
}  

输出结果: 

hello, guy!
hello, guy!
Yes, Man!
Yes, Woman!

 

3. 在以对象名来调用其成员函数时, 会使用其实际类型


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();   
    }  
}  
爸爸在吃饭
儿子在吃饭

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值