继承在Java中,当类A继承类B时,堆中会发生什么
在Java中,假设我们有两个类A
和B
,这样B
继承A
和A
有三个私有字段和一个带三个参数的构造函数:
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 楼答案
类对象像其他对象一样加载到堆中。这个对象只是代表类
Oracle official 'Understanding Memory guide'
很好,你可以阅读整个文档,了解类加载器是如何工作的,你不会发现任何“类被加载到堆中”的东西。。此外,你还可以在互联网上进行初步搜索,以获得进一步的澄清
Class B
将完美编译现在请按顺序提问:
您无法确定它们的顺序取决于jvm如何管理它们的顺序,私有成员不是继承的,而是存在于父对象(super)中的实例化对象中
换句话说,是的,子类的实例将具有父类的私有字段的副本。 然而,它们对于子类是不可见的,所以访问它们的唯一方法是通过父类的方法
通常,在创建
A
和B
的实例之后,序列会类似A.class
对象的引用(在生成A
类实例之后)B.class
对象的引用(在生成B
类实例之后)A
实例变量块(仅a、b、c)B
实例变量块(本例中无)然而,JVM的每个实现都可以自由选择如何分配它们
当你呼叫
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规范!它们占据了物体内部的空间。它们对子类不可见,但它们在该实例中