繁体   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