有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

在Java中,假设我们有两个类AB,这样B继承AA有三个私有字段和一个带三个参数的构造函数:

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;
 }
}

下面是B

public class B extends A {        

  public B() {
    super(1,2,3);
 }
}

我们考虑下面的测试类

public class TestA {

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

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

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


共 (1) 个答案

  1. # 1 楼答案

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

    Oracle official 'Understanding Memory guide'

    很好,你可以阅读整个文档,了解类加载器是如何工作的,你不会发现任何“类被加载到堆中”的东西。。此外,你还可以在互联网上进行初步搜索,以获得进一步的澄清

    Class B将完美编译

    现在请按顺序提问:

    what is the ordered process in the heap that occurs when creating the class A with private fields and inheriting it by the class B?

    您无法确定它们的顺序取决于jvm如何管理它们的顺序,私有成员不是继承的,而是存在于父对象(super)中的实例化对象中

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

    What happens in the Heap when creating instances of these two classes?

    通常,在创建AB的实例之后,序列会类似

    1. A.class对象的引用(在生成A类实例之后)
    2. B.class对象的引用(在生成B类实例之后)
    3. 对象实例变量块
    4. A实例变量块(仅a、b、c)
    5. B实例变量块(本例中无)

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

    We know also that a subclass cant inherit the private fields of its superclass, so what happens exactly when the constructor B() is called?

    当你呼叫B()

    B b = new B();
    

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

    那之后会发生什么呢?无传递给super();的值被传递给A(int a, int b, int c),然后分配给A的实例变量,但这并不意味着这些私有字段现在可以被B访问。。您刚刚将值传递给了超级类构造函数,仅此而已

    编辑

    如果您想更好地理解堆和堆栈,请参阅this question

    编辑-2

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

    最终编辑-3

    在OP关于超级阶级私人成员的评论中

    Take a look at this这个问题的答案将消除您对继承成员和不可访问的私有成员的混淆,因为子类实例是超级类的实例,它的实例包含父类的所有字段!那个孩子看不到私人成员!!这就是您所指的JLS规范!它们占据了物体内部的空间。它们对子类不可见,但它们在该实例中