[英]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
的內部calculate
和i
的內部main
最初可能“點”到同一個對象,但他們不是“同一”。
所以,如果你改變i
里面的calculate
,從您的乘法產生的對象,你不會自動改變的參考i
的內main
。
對於Customer
,情況有所不同。 您永遠不會更改setAName
中c
setAName
位置。 您更改一個參考對象的內部 ,但兩者customer
的內部main
和c
在setAName
仍然指向一個對象!
這里有兩張簡陋的Paint圖紙來解釋我的意思(以0x
數字是參考):
對於整數示例:
對於客戶示例:
不要猶豫,再問任何問題。
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.