当类A在Java中继承B类时,堆中会发生什么

pen*_*nol 9 java heap inheritance jvm instance

在java中我们假设我们有两个类和A,这样B继承A和A有3个私有字段和构造函数有三个参数

public class A {
private int a ;
private int b ;
private int c ;

 public A(int a, int b, int c) {
    this.a = a;
    this.b = b;
    this.c = c;
 }
}
Run Code Online (Sandbox Code Playgroud)

这是B级

public class B extends A {        

  public B() {
    super(1,2,3);
 }
}
Run Code Online (Sandbox Code Playgroud)

我们考虑以下测试类

public class TestA {

        public static void main(String[] args) {
            A a = new A(1,2,3);
            B b = new B();        
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是在创建具有私有字段的类A并由类B继承它时,堆中的有序进程是什么?在创建这两个类的实例时,堆中会发生什么?内存分配是如何发生的以及类如何在计算机memry中进行交互?

我们也知道子类不能继承其超类的私有字段,那么在A调用构造函数时会发生什么呢?

Sha*_*dge 5

类对象像任何其他对象一样加载到堆中。这个对象只代表类。

Oracle 官方“理解内存指南”

和旧的Java 规范,您可以阅读整个文档,了解类加载器的工作原理,您将找不到任何“类加载到堆中”的内容。此外,您可以在互联网上进行一些初步搜索以进一步说明。

Class B 将完美编译。

现在你的问题按他们的顺序:

创建具有私有字段的类 A 并由类 B 继承它时发生的堆中的有序过程是什么?

您无法根据 jvm 管理它们的顺序来确定它们的顺序,私有成员不是继承的,而是存在于父级(超级)的实例化对象中。

换句话说,是的,子类的实例将具有父类的私有字段的副本。然而,它们对子类不可见,因此访问它们的唯一方法是通过父类的方法。

创建这两个类的实例时,堆中会发生什么?

通常,序列将类似于在您创建A和B

  1. 对A.class对象的引用(在创建A类实例之后)
  2. 对B.class对象的引用(在创建B类实例之后)
  3. 对象实例变量块
  4. A实例变量块(仅 a、b、c)
  5. B实例变量块(在这种情况下没有)

然而,JVM 的每个实现都可以自由选择如何分配每个实现。

我们也知道子类不能继承其超类的私有字段,那么当构造函数 B() 被调用时到底发生了什么?

你打电话时 B()

B b = new B();
Run Code Online (Sandbox Code Playgroud)

它会调用 super(1,2,3)

那么在那之后会发生什么呢?没什么价值传递给super();传递给A(int a, int b, int c),然后分配到的实例变量A,但这并不意味着这些私有字段现在访问B..你刚过值超类的构造函数多数民众赞成。

--编辑--

如果您想更好地了解堆和堆栈,请参阅此问题

--编辑-2 --

如果您花一些时间来研究这个wiki,它拥有关于 JVM 的一切,包括它在堆中的进程和其他内存结构。

--最终 EDIT-3 --

在 OP 对 Super 类的私有成员的评论中

看看这个这个问题的答案将清除您对继承成员和不可访问的私有成员的困惑,因为子类实例是超类的实例,它的实例具有父类的所有字段!私人成员对那个孩子不可见!!这就是您所指的 JLS 规范!它们占据了物体内部的空间。它们对子类不可见,但它们在该实例中。