2013-11-21 120 views
7

這看起來像一個愚蠢的問題,但我發現很難做到這一點。我問過不同的人,但無法得到理想的答案。在Java中調用某個方法後會發生什麼

我想知道在Java中調用常規方法(在單線程環境中提供)後會發生什麼。

我的理解是:

  1. 目前所有的堆棧變量POP操作,並存儲某處(哪裏?)
  2. 目前的方法調用停止
  3. 新調用方法的參數都推到堆棧
  4. 方法代碼運行
  5. 該方法完成運行後,堆棧將再次清空,舊的堆棧內容將再次被恢復。 (如果函數返回一個值會發生什麼?)。
  6. 代碼繼續調用方法。

這是一個非常不完整,可能是錯誤的答案。有人可以提供更詳細的描述嗎?

非常感謝。

+4

我很確定棧沒有被清空,否則你永遠不會得到StackOverflowException。 – MightyPork

+0

您的步驟(1)和(5)不會發生。還有一個步驟,即將方法的返回值推送到堆棧上(除非它當然無效)。 –

+1

閱讀http://www.javaworld.com/jw-06-1997/jw-06-hood.html - 這裏都詳細描述了它。 –

回答

3

不,這其實是相當準確:

1)當前堆棧變量保持堆棧

2)目前的方法暫停

3)新調用方法的參數都推到上堆棧

4)的方法,代碼運行

5)之後,該方法運行完畢後,我們彈出堆棧。被調用方法的堆棧變量不再有效 - 此時它們不再「存在」。

6)我們的返回值(如果有的話)傳遞給調用者

7)的代碼,繼續與調用方法。所有的堆棧變量保持不變。

==============================

附錄:

@Kevin -

  • 從概念上講,我認爲你知道它是正確的。我澄清了幾點,我希望有所幫助。

  • 如果您想深入瞭解JVM如何實現「方法調用」,David Wallace的鏈接非常好。

  • 這是一個很好的概述「堆棧」是如何工作的。任何堆棧,調用任何子程序 - 不僅僅是Java:http://en.wikipedia.org/wiki/Call_stack

  • 最後,Marko Topolnik是正確的。「現實」幾乎總是非常複雜,以至於它不適用於一個簡單的,一刀切的答案。但我絕對認爲你的理解是好的。至少在10,000英尺的水平。

IMHO ...

+0

推送/彈出被調用地址的地址如何? – MightyPork

+0

怎麼辦?是:當函數被調用時,地址被推送到堆棧,並在函數返回時從堆棧彈出。 – paulsm4

1

對於解釋,假定一個實例方法,並採取一些小的自由:

  1. 的對象的指針被用於引用該對象,並從那裏Class對象。
  2. 方法指針位於Class對象中。 (將方法名稱轉換爲方法索引的查找大部分是在加載類時完成的,因此這基本上只是一個數組索引操作。)
  3. 通常,某種「標記」被壓入JVM堆棧。這將包含調用者的指令指針和一個指向其堆棧底部的指針。 (在這裏有很多不同的實現方式。)
  4. 該方法的定義被用來查看需要多少局部變量。許多空白元素被壓入堆棧。
  5. 對象(「t​​his」)指針存儲在本地var 0中,並且任何parms都存儲在1,2,3 ...中。
  6. 控制轉移到被調用的方法。

返回時,堆棧被彈出到開始調用的位置,任何返回值被壓入堆棧,並且控制權被轉回給調用者。

編譯代碼在概念上是相似的,只有它使用「C」堆棧,並且JITC環境中的解釋代碼將使用JVM堆棧和「C」堆棧。

相關問題