[英]What happens in the heap when class A inherits class B in Java
在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()
時會發生什么?
類對象像任何其他對象一樣加載到堆中。 這個對象只代表Class。
和舊的java規范一樣 ,你可以閱讀整個文檔作為類加載器的工作方式,你將找不到任何“類在堆中加載”的東西。更多你可以在互聯網上進行一些初步搜索以進一步說明。
Class B
將完美編譯。
現在你的問題由他們的訂單:
在創建具有私有字段的類A並由類B繼承它時,堆中的有序進程是什么?
你無法確定它們的順序,直到jvm如何管理它們的順序,私有成員不是繼承的,而是存在於父(超級)中的實例化對象中。
換句話說,是的,子類的實例將具有父類的私有字段的副本。 但是它們對子類是不可見的,因此訪問它們的唯一方法是通過父類的方法。
在創建這兩個類的實例時,堆中會發生什么?
通常,序列將類似於您創建A
和B
實例之后
A.class
對象的引用(在創建A
類實例之后) B.class
對象(在制作B
類實例之后) A
實例變量(僅A,B,C) B
實例變量的塊(在這種情況下沒有) 但是,JVM的每個實現都可以自由選擇如何分配它們。
我們也知道子類不能繼承其超類的私有字段,那么在調用構造函數B()時會發生什么呢?
當你打電話給B()
B b = new B();
它會叫super(1,2,3)
那之后會發生什么? 沒有傳遞給super();
的值super();
傳遞給A(int a, int b, int c)
,然后分配給A
的實例變量,但這並不意味着B
現在可以訪問這些私有字段..你只是將值傳遞給超類構造函數,這些都是。
- 編輯 -
如果您想要更好地理解堆和堆棧,請參閱此問題
- EDIT-2 -
如果你花一些時間來研究這個wiki ,它就擁有了JVM的一切,包括它在Heap和其他內存結構中的過程
- 最終編輯3 -
在OP關於超級私人成員的評論的背景下
看一下這個問題的答案將清除你對繼承成員和不可訪問的私有成員的困惑,因為子類實例是超類的實例,它的實例具有父類的所有字段! 那個孩子看不到私人會員! 這就是你所指的JLS規范! 他們占據了對象內部的空間。 它們對於子類是不可見的,但它們存在於該實例中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.