我曾经学习过字符串是不可变的优点,因为这有助于提高内存性能。
有人能给我解释一下吗?我在网上找不到相关信息。
我曾经学习过字符串是不可变的优点,因为这有助于提高内存性能。
有人能给我解释一下吗?我在网上找不到相关信息。
不可变性(针对字符串或其他类型)可以带来许多好处:
不可变字符串也有助于避免将字符串用作缓冲区的诱惑。 C/C++程序中的许多缺陷与使用裸字符数组组合或修改字符串值导致的缓冲区溢出问题有关。将字符串视为可变类型鼓励使用更适合于缓冲区操作的类型(请参阅.NET或Java中的StringBuilder
)。
StringBuilder
只是解决不可变字符串连接缓慢的一种方法,并且与有效的堆管理系统相关联的COW模式相比几乎没有好处。 COW可以使您的缓冲区访问同时安全又快速。 - Arnaud Bouchezs1
和s2
应分别持有对“StringRef”的单独实例的唯一引用,并且s1=s2;
应该被执行为s1.CopyFrom(s2);
,而不改变s1
所引用的“StringRef”的实例。Java和.NET语言不支持这样的概念,但C++支持(至少在不必与其他.NET语言交互的代码中)。 - supercat不可变字符串易于复制,因为您无需复制所有数据 - 只需复制指向数据的引用或指针。
任何类型的不可变类在多线程环境下更易于使用,只需要同步销毁即可。
也许我的回答已经过时了,但可能有人会在这里找到新的信息。
为什么Java中的字符串是不可变的,以及它的好处:
从根本上讲,如果一个对象或方法希望向另一个对象传递信息,它有几种方法可以实现:
它可以提供一个包含信息的可变对象的引用,并且接收方承诺永远不会修改它。
它可以提供一个包含数据的对象的引用,但它并不关心其内容。
它可以将信息存储到一个可变对象中,预期的数据接收者知道这个对象(通常是由该数据接收者提供的对象)。
它可以返回一个包含信息的不可变对象的引用。
其中,方法#4是最容易的。在许多情况下,可变对象比不可变对象更易于处理,但是在没有将信息复制到其他位置之前,没有简单的方法可以与“不可信”代码共享可变对象中的信息。相比之下,持有引用的不可变对象中保存的信息可以通过仅分享该引用的副本来轻松地共享。
想象一下各种字符串坐在一个公共池中。然后,字符串变量指向池中的位置。如果您复制一个字符串变量,则原始字符串和副本共享相同的字符。这种共享效率超过了通过提取子字符串和连接来进行字符串编辑的低效性。
a) 想象一下没有使字符串不可变的StringPool设施,这是不可能的,因为在字符串池的情况下,一个字符串对象/字面量例如“Test”被许多引用变量引用,所以如果其中任何一个更改值,则其他变量也会自动受到影响,例如:
String A =“Test”和String B =“Test”
现在String B调用“Test”。toUpperCase()将同一对象更改为“TEST”,因此A也将是“TEST”,这是不可取的。
b) Java中String不可变的另一个原因是允许String缓存其哈希码,由于Java中的String是不可变的,因此它缓存其哈希码并且不会在每次调用String的hashcode方法时计算,这使得它作为哈希映射键非常快速。