[英]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.