关于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;
}
我了解堆栈和堆中正在发生的事情。在这种情况下,不会返回该变量,也没有对Heap的引用。
在此示例中:
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是一个对象,我假设它是在堆中创建的!
有趣的是,如果我将Integer包装在Customer中,我将得到50而不是5。
为什么会这样?难道不是在堆中创建了整数类型吗?
答案 0 :(得分:1)
这是引用问题,而不是堆和栈问题。
在调用方法calculate
时,您传递了一个引用(在您的情况下为i
的{{1}})。
诀窍是Java将在main
内创建一个新引用。因此,calculate
内的i
和calculate
内的i
最初可能“指向”同一对象,但它们不是“相同”。
因此,如果您将main
内的i
更改为乘法所得到的对象,则不会自动更改calculate
内的i
的引用
与main
不同。您永远不会更改Customer
中c
指向的位置。您在对象的内部中更改了一个引用,但是setAName
中customer
内部的main
和c
中的setAName
仍指向该对象! / p>
这里有两张简陋的Paint图纸来解释我的意思(以0x
开头的数字是参考):
对于整数示例:
对于客户示例:
不要犹豫,再提出任何问题。
我希望这会有所帮助。