java - Java 内存管理对象与原始类型
问题描述
我对有关 Java 内存管理的几点感到有些困惑。
了解了堆栈和堆之间的区别,我去看了一个适当的例子,说明当我们执行一些代码时这些内存是什么。
我以这几行为例
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 包装在 Customer 中,我将得到 50 而不是 5。
为什么会这样?不是在堆中创建整数类型吗?
解决方案
这是引用的问题,而不是堆和堆栈的问题。
调用 methodcalculate
时,您传递一个引用(在您的情况下,i
from main
)。
诀窍是,Java 将在calculate
. 所以i
inside ofcalculate
和i
inside ofmain
最初可能“指向”同一个对象,但它们不是“相同的”。
因此,如果将i
inside of更改calculate
为乘法产生的对象,则不会自动更改i
inside of的引用main
。
有了Customer
,就不一样了。你永远不会改变c
insetAName
点的位置。您更改了对象内部的一个引用,但customer
内部main
和内部仍然指向该对象c
!setAName
这里有两张糟糕的油漆图来解释我的意思(前缀数字0x
是参考):
对于整数示例:
对于客户示例:
如有任何问题,请随时回来。
我希望这有帮助。
推荐阅读
- tensorflow2.0 - Yolov3 到 Tensorrt:tf-keras Lambda 层的自定义插件
- amazon-web-services - 将数据从 Elasticsearch 实时发送到 AWS 数据库
- ansible - Ansible:幂等且安全地处理临时文件
- pact - fallbackTag 不起作用并且代码抛出 NoPactsFoundException
- r - 找出运行选定表格栅格的天数
- angular - 使用动态 id 选择器在 angular v10 中显示动态组件
- microsoft-graph-api - 是否可以使用 Microsoft Graph API 在 Microsoft To Do 任务上设置类别?
- python - Python“sklearn”值错误
- javascript - 如果选中“桌面站点”,则强制缩小移动浏览器/页面
- wso2 - 在 WSO2 Integration Studio / Micro Integrator 上关闭 SSL 验证