String是不可变的有什么好处?

时间:2010-08-04 15:59:46

标签: string immutability

一旦我研究了字符串不可变的优点,因为它可以改善内存中的性能。

有人可以向我解释一下吗?我无法在互联网上找到它。

7 个答案:

答案 0 :(得分:34)

不变性(对于字符串或其他类型)可以有很多优点:

  • 它可以更容易推理代码,因为您可以对变量和参数进行假设,否则无法做到。
  • 它简化了多线程编程,因为从无法更改的类型中读取始终是安全的并行执行。
  • 通过允许将相同的值组合在一起并从多个位置引用,可以减少内存使用量。 Java和C#都执行字符串实习,以降低嵌入代码中的文字字符串的内存成本。
  • 它简化了某些算法(例如那些采用回溯或价值空间划分的算法)的设计和实现,因为以前计算的状态可以在以后重复使用。
  • 不变性是许多函数式编程语言的基本原则 - 它允许将代码视为从一种表示到另一种表示的一系列转换,而不是一系列突变。

不可变字符串也有助于避免使用字符串作为缓冲区的诱惑。 C / C ++程序中的许多缺陷与使用裸字符数组组成或修改字符串值导致的缓冲区溢出问题有关。将字符串视为可变类型可以鼓励使用更适合缓冲区操作的类型(请参阅.NET或Java中的StringBuilder)。

答案 1 :(得分:9)

考虑替代方案。 Java没有const限定符。如果String对象是可变的,那么将引用传递给字符串的任何方法都可能具有修改字符串的副作用。不可变的字符串消除了对防御性副本的需要,并降低了程序错误的风险。

答案 2 :(得分:5)

不可变的字符串复制起来很便宜,因为您不需要复制所有数据 - 只需复制引用或指向数据的指针。

任何类型的不可变类在多个线程中都更容易使用,唯一需要的同步就是销毁。

答案 3 :(得分:0)

想想坐在公共池上的各种字符串。然后,字符串变量指向池中的位置。如果您复制字符串变量,则原始副本共享相同的字符。通过提取子串和连接,这些共享效率超过了字符串编辑的低效率。

答案 4 :(得分:0)

a)想象一下StringPool工具没有使字符串不可变,它根本不可能,因为在字符串池的情况下,一个字符串对象/文字,例如“测试”已被许多参考变量引用,因此如果其中任何一个改变了值,其他参数将自动受到影响,即可以说 字符串A =“测试”和字符串B =“测试” 现在String B称为“Test”.toUpperCase(),它将同一个对象更改为“TEST”,因此A也将是“TEST”,这是不可取的。
    b)为什么String在Java中是不可变的另一个原因是允许String缓存其哈希码,Java中的不可变String缓存其哈希码,并且不会在每次调用String的哈希码方法时计算,这使得它作为hashmap键非常快

答案 5 :(得分:0)

也许,我的答案已经过时,但可能有人会在这里找到新的信息。

为什么Java String是不可变的以及为什么它是好的:

  • 你可以在线程之间共享一个字符串,并确保没有人会改变字符串并混淆另一个线程
  • 你不需要锁。几个线程可以使用不可变的字符串而不会发生冲突
  • 如果你刚刚收到一个字符串,你可以确定没有人会在那之后改变它的价值
  • 你可以有很多字符串重复 - 它们将指向一个实例,只指向一个副本。这节省了计算机内存(RAM)
  • 您可以在不复制的情况下执行子字符串, - 通过创建指向现有字符串元素的指针。这就是Java子串操作实现如此之快的原因
  • 不可变字符串(对象)更适合用作哈希表中的键

答案 6 :(得分:0)

从根本上说,如果一个对象或方法希望将信息传递给另一个,有几种方法可以做到:

  1. 它可以提供对包含信息的可变对象的引用,以及接收者承诺永远不会修改的对象。

  2. 它可能会引用一个包含数据的对象,但其内容并不关心。

  3. 它可以将信息存储到预期数据接收者知道的可变对象中(通常由该数据接收者提供)。

  4. 它可能会返回对包含该信息的不可变对象的引用。

  5. 在这些方法中,#4是迄今为止最简单的方法。在许多情况下,可变对象比不可变对象更容易使用,但是没有简单的方法可以与不可信任的对象共享#34;编码可变对象中的信息,而不必先将信息复制到其他内容。相比之下,通过简单地共享该引用的副本,可以轻松地共享一个持有引用的不可变对象中的信息。