2015-04-06 60 views
0

下面,你會看到兩個非常簡單的Java程序。在第一個程序中,我沒有使用returnTrue()方法的返回值,在第二個程序中,我將它分配給一個靜態字段。使用方法的返回值和離開它們有什麼區別?

第一程序:

package test; 
public class Test { 
    public static void main(String[] args) { 
     returnTrue(); 
     System.out.println("Finished!"); 
    } 

    public static boolean returnTrue() { 
     return true; 
    } 
} 

第二方案:

package test; 
public class Test { 
    public static boolean Result; 

    public static void main(String[] args) { 
     Result = returnTrue(); 
     System.out.println("Finished!"); 
    } 

    public static boolean returnTrue() { 
     return true; 
    } 
} 

都工作得很好,並打印在輸出"Finished!"

現在,我想知道內存中會發生什麼,如果我把returnTrue()的行放在一個無限循環中?就我所知,在第二個程序中,它將true分配給無限存儲器中的特定地址(即地址Result)。 (對吧?)

但我對第一個程序沒有任何意見。在這種情況下會發生什麼? JRE是否選擇一個隨機地址並將所有返回值分配給相同的地址?或者它將每個返回值分配給一個特定的地址?甚至它離開它,並沒有把它分配給任何地址?

+0

你能向我們展示你想要探索的行爲的最終代碼嗎? – Andremoniy 2015-04-06 08:13:22

+0

不可以。您無法控制內存地址 - 新對象,「返回」值 - 將始終分配在內存中。然後將創建該地址的_reference_。 _reference_是通過值**傳遞的。是否將它分配給變量是無關緊要的。 – 2015-04-06 08:13:36

+2

聽起來像你想知道當一個函數返回一個值時會發生什麼,但是你沒有把該值賦給任何變量。什麼都沒有發生 - 價值沒有被存放在任何地方; JVM只是將它放在地板上。 – dnault 2015-04-06 08:14:10

回答

4

當一個方法返回時,返回值通常留在內存中的線程堆棧中,無論調用代碼在哪裏停止。 A stack是通常用於此目的的重要數據結構。

假設我們有一個像一些代碼如下:

void m1() { 
    int i; 
    int j; 
    boolean b = m2(); 
} 

boolean m2() { 
    float f; 
    float g; 
    return true; 
} 

m1開始執行,堆棧開始延伸到預留空間的局部變量:

int 
int 
boolean 

m2被調用,堆棧再次延伸:

int 
int 
boolean 
    float 
    float 

m2返回,堆棧以相反的順序解開:

int 
int 
boolean 

注意,堆棧中的最後一個空間方便我們爲m2返回值,其中true被存儲在本地變量。

當您將返回值賦予某個值時,將原始值或對象引用從堆棧複製到您分配給它的位置(本例中爲靜態字段)。

如果您不將它分配給任何東西,則返回值將被忽略。

[…]如果我把returnTrue()的行放在一個無限循環中,內存中會發生什麼?

它重複執行上述步驟。

JRE是否選擇一個隨機地址並將所有返回值分配給相同的地址?或者它將每個返回值分配給一個特定的地址?

請參閱上面的內容,將其放入堆棧。

+0

_當您將返回值分配給某個值時,該值將從堆棧複製到您分配給它的位置_。這不是嚴格講真,Java通過價值傳遞_references_;除了基元的情況。 – 2015-04-06 08:20:42

+1

@BoristheSpider在這種情況下,引用的值被複制。 – Radiodef 2015-04-06 08:22:10

+0

當我將它分配給靜態字段時,它將釋放並重新用於下次調用之前佔用的堆棧地址,對吧?相反,當我不分配它時,下一次調用使用另一個堆棧地址,對吧?它不會使堆棧溢出錯誤? – Abraham 2015-04-06 08:23:08

相關問題