簡體   English   中英

Java內存管理對象與原始類型

[英]Java memory management Objects vs Primitive Types

關於Java內存管理的幾點,我有些困惑。

理解了Stacks和Heap之間的區別是什么,我去看了一個有關在執行代碼時這些內存是什么的正確示例。

我以這幾行為例

public static void main(String[] args)
{
    int a = 5;
    calculate(a);
    System.out.println(a); //will print 5 not 50
}
private static void calculatee(int a)
{
    a = a * 10;
}

我了解堆棧和堆中正在發生的事情。 在這種情況下,不會返回變量,也沒有對堆的引用。

而在此示例中:

public static void maina(String[] args)
{
    Customer customer = new Customer("John");
    setAName(customer);
    System.out.println(customer.getName()); // this will return Philip
}

private static void setAName(Customer c)
{
    c.setName("Philip");
}

這次可以看到對象的狀態發生了變化!

堆棧不是共享的思想線程,而是共享的! 在我打印時,目標客戶已將其價值從Jhon更改為Philip,這對我來說很有意義! 大! 都說得通!

但是,我期望如果我能做到這一點

public static void main(String[] args)
{
    Integer i = new Integer(5);
    calculate(i);
    System.out.println(i); // printing 5 and not 50
}
private static void calculate(Integer i)
{
    i = i * 10;
}

我會得到50而不是5!

在這種情況下,Integer是一個對象,我假設它是在堆中創建的!

有趣的是,如果我將整數包裝在客戶中,我將得到50而不是5。

為什么會這樣呢? 難道不是在堆中創建了整數類型嗎?

這是引用的問題,而不是堆和棧的問題。

當調用方法calculate ,您傳遞了一個引用(在您的情況下, i來自main )。

訣竅是,Java將在calculate內部創建一個新引用。 所以, i的內部calculatei的內部main最初可能“點”到同一個對象,但他們不是“同一”。

所以,如果你改變i里面的calculate ,從您的乘法產生的對象,你不會自動改變的參考i的內main

對於Customer ,情況有所不同。 您永遠不會更改setANamec setAName位置。 您更改一個參考對象的內部 ,但兩者customer的內部maincsetAName仍然指向一個對象!

這里有兩張簡陋的Paint圖紙來解釋我的意思(以0x數字是參考):

對於整數示例:

整數圖

對於客戶示例:

客戶圖

不要猶豫,再問任何問題。

我希望這有幫助。

暫無
暫無

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

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