簡體   English   中英

繼承技術如何運作?

[英]How does inheritance technical work?

我即將在我的公司(我是一名實習生)中介紹Java中的繼承。 我想我已經明白了,我也知道如何使用它。 但有一點不太確定。 存儲在存儲器中的方法在哪里。 對象如何知道方法的位置?

例如:

我們有這門課。

class Animal {
    private String desc1;
    protected String desc2;

    public void breath() {
    }

    public void eat() {
    }
}

而這堂課:

  class Dog extends Animal() {
        public void bark() {
        }
    }

我們現在創建一個Dog類的對象:

狗狗=新狗();

所以現在我的問題是: 類被加載到堆中。 所以狗和動物都在堆里。 (編輯:多數民眾贊成錯了,類沒有加載到堆中,看下面的答案。)。 所以,讓我們說我們做dog.bark() 狗如何知道樹皮方法在堆中的位置? 知道狗類在哪里? 接下來我們制作dog.eat():所以當狗知道Dog在哪里時,Dog會知道Animal在哪里或者狗知道Animal在哪里嗎? 知道我的意思是它有一個地址在堆上。 當我覆蓋一個方法時怎么樣? 存儲在哪里?

thx求助。

首先,這是JVM依賴並且對這些問題應該如何解決在JLS或JVM規范沒有要求,只是他們應該得到解決。

狗如何知道樹皮方法在堆中的位置?

通常你有所謂的虛方法表 ,或簡稱v表。 您可以將此視為表映射方法標識符(例如bark )到函數指針。 也就是說,如果你調用bark ,VM會查看它的v-table並調用bark指向的方法。 擴展類並重寫方法時,只需交換方法指針以指向覆蓋函數。

狗如何知道樹皮方法在堆中的位置? 知道狗類在哪里?

方法和類不以與實例相同的意義存儲在堆上。 他們為什么?

也許你和我開始使用OO編程時有同樣的誤解。 我想如果我實例化10 Dog ,我會得到10種樹皮方法。 這不是真的。 實例化對象時“得到”的基本上是成員變量和this引用。 然后,您可以this引用視為在調用非靜態方法時傳遞的額外參數。

不,類沒有加載到堆中(至少不是你可以認為是Java中的堆),而是加載到一個名為PermGen space的內存部分。

我無法確切地告訴你Java如何存儲這些信息,但我認為它類似於C ++的方式( vtable ),因為它通常是在JVM本機代碼中完成的。

首先,在java中創建的任何對象在對象頭中的某處都有一個類引用。 鏈接“靜態”(不覆蓋,JIT知道是否有任何方法被覆蓋但是某些子類)方法很簡單,它可以內聯或只是調用代碼所在的某個特定點。

這種方式更復雜,因為優化的代碼是使用寄存器中保存的值調用的,而java規范要求它們在堆棧上。

調用覆蓋方法以幾種方式完成:

  • 動態檢查實例並像靜態示例一樣調度調用,這是一個比較/分支調用,比快
  • 內聯緩存
  • 或者已經提到的v-table調用。 v表是最慢的

但是,了解處理器執行代碼的方式以及調用/內聯的方法等是一個很大的主題。 我想其他一些基本概念都缺失了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM