【问题标题】:How memory allocates to superclass and subclass members when we create object of subclass using superclass reference variable当我们使用超类引用变量创建子类对象时,内存如何分配给超类和子类成员
【发布时间】:2019-01-28 11:18:15
【问题描述】:
class A {
    int y = 10;

    void m1() {
        System.out.println("This is M1");
        int b = 20;
    }
}

public class B extends A {

    int x = 10;
    int y = 20;

    void m1() {
        System.out.println("This is M2");
    }

    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.y);
        a.m1();
    }

}

内存分配图表/图表是什么?

【问题讨论】:

标签: java


【解决方案1】:
  • new B:
    • B 已分配,B 的大小(包括 A 的大小)所有字段默认
    • B() 的构造函数:
      • super.A() 调用;递归:
        • A()的构造函数:
        • super.Object() 调用;递归
        • A 的所有初始化字段都被赋值:A.this.y = 10;
        • 其余的 A 构造函数语句被执行
      • B 的所有初始化字段都被赋值:B.this.x = 10; B.this.y = 20;
      • 其余的 B 构造函数语句被执行

所以分配主要是在new中完成的。

在构造函数和字段初始化中完成的分配可以在下一个角转换中说明(要避免):

class A {
    A() {
        init(); // VERY BAD STYLE
    }
    protected void init() {
    }
}

class B extends A {
    String s1 = null;
    String s2;
    String s3 = "s3";
    String s4;
    String s5 = "s5";
    B() {
        // s1: null, s2: null, s3: null, s4: null, s5: null
        // super() called, calling init()
        // s1: "i1", s2: "i2", s3: "i3", s4: null, s5: null
        // field initialisation:
        // - s1 = null; s3 = "s3"; s5 = "s5";
        // s1: null, s2: "i2", s3: "i3", s4: null, s5: "s5"
        // remaining code of constructor
    }

    @Override
    protected void init() {
        // s1: null, s2: null, s3: null, s4: null, s5: null
        s1 = "i1";
        s2 = "i2";
        s3 = "i3";
        // s1: "i1", s2: "i2", s3: "i3", s4: null, s5: null
    }
}

上面显示了字段的起始生命周期,以及如果有人在构造函数中使用可覆盖方法时的意外时刻。

它还表明在 A 的构造函数中已经存在超字段(默认值null, 0, false, 0.0, ...)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多