更改String对象时的Java字符串不可变性存储

时间:2015-09-14 12:02:44

标签: java string oop heap immutability

据我所知,如果使用文字初始化String,则会在String Pool中分配一个空格,如果使用新的Keyword初始化,则会创建String的对象。但我对下面写的案例感到困惑。

我的问题是,如果使用new关键字创建String,然后使用文字更新值?

E.g。

String s = new String("Value1");  -- Creates a new object in heap space

那么如果写下面的语句怎么办呢。

s = "value2";

所以我的问题是,

1它会在字符串池中创建字符串文字,还是会更新该对象的值?

2如果它在String Pool中创建了一个新的文字,那么当前存在的对象会发生什么?是否会被破坏,或者它会在那里被调用垃圾收集器。

这是一个小字符串,如果字符串是数千个字符,那么我只是担心它使用的空间。所以我的关键问题是空间。

分配文字后会立即从堆中释放空间吗?

任何人都可以解释从第一个语句到第二个语句的值是什么,以及内存区域(堆和字符串池)会发生什么。

2 个答案:

答案 0 :(得分:9)

修改String s

运行

值未更新

s = "value2";

在Java中,除原语类型外,所有其他变量都是引用到对象。这意味着只有s指向一个新值。

不变性可确保对象的状态在构建后无法更改。换句话说,没有办法在Java中修改任何String对象的内容。例如,如果您已创建 new 字符串,则会以某种方式存储新文本。

垃圾收集

This answer已经提供了深入的答案。如果您不想阅读完整的答案,请在简短的摘要下面,但它会省略一些细节。

默认情况下,s = s+"a";对象不会被实现,因此适用垃圾收集的常规规则。这些只是普通的物体。

您的代码中的常量字符串通常永远不会被删除,因为最终您可能会引用这些字符串。

然而,答案中有一个侧面说明,有时候动态(非)加载类,在这种情况下,可以从池中删除文字。

回答您的其他问题:

  

分配文字后会立即从堆中释放空间吗?

,这不会真正有效:垃圾收集器需要分析要删除的对象。您可能与其他对象共享对旧字符串的引用,因此无法保证可以回收该对象。此外,只要您不需要向操作系统请求额外的内存(将其与您的计算机进行比较,只要您可以将所有数据存储在硬盘中),存储数据不再有用就没有太大问题。磁盘驱动器,你真的不必担心无用的文件,从你需要购买额外的驱动器的那一刻起,你可能会先尝试删除一些文件)。分析需要一些计算工作。通常,垃圾收集器仅在(几乎)耗尽内存时运行。所以你不应该担心记忆。

  

任何人都可以解释从第一个语句到第二个语句的值是什么,以及内存区域(堆和字符串池)会发生什么。

你的第一个字符串:

new String(...)

是对堆的引用。如果调用该命令,它将在堆上为字符串分配空间。

现在,如果你打电话:

String s = new String("Value1");

s = "value2"; String Pool 的一个元素,它会一直存在,直到你的程序结束。

由于您不再引用旧字符串("value2")。该对象是收集的候选对象。如果垃圾收集器稍后走过,它将从堆中删除该对象并将该空间标记为空闲。

答案 1 :(得分:0)

  

如果您需要更改字符串,您始终可以创建一个包含该字符串的新字符串   修改。

  • Java定义了一个名为StringBuffer的String对等类,它允许更改字符串。