为什么他们决定在Java和。net(和其他一些语言)中使字符串不可变?为什么不让它变呢?


当前回答

不可变性与安全性并没有那么紧密的联系。为此,至少在。net中,你得到了SecureString类。

稍后编辑:在Java中,你会发现GuardedString,一个类似的实现。

其他回答

不变性很好。参见有效的Java。如果每次传递String时都必须复制它,那么这将是大量容易出错的代码。您还会混淆哪些修改会影响哪些引用。同样地,Integer必须是不可变的才能像int一样,string必须是不可变的才能像原语一样。在c++中,按值传递字符串是这样做的,源代码中没有明确提到。

线程安全和性能。如果一个字符串不能被修改,那么在多个线程之间传递引用是安全且快速的。如果字符串是可变的,则总是必须将字符串的所有字节复制到新实例,或者提供同步。一个典型的应用程序在每次需要修改字符串时将读取字符串100次。参见维基百科关于不变性的内容。

至少有两个原因。

第一-安全http://www.javafaq.nu/java-article1060.html

The main reason why String made immutable was security. Look at this example: We have a file open method with login check. We pass a String to this method to process authentication which is necessary before the call will be passed to OS. If String was mutable it was possible somehow to modify its content after the authentication check before OS gets request from program then it is possible to request any file. So if you have a right to open text file in user directory but then on the fly when somehow you manage to change the file name you can request to open "passwd" file or any other. Then a file can be modified and it will be possible to login directly to OS.

第二-内存效率http://hikrish.blogspot.com/2006/07/why-string-class-is-immutable.html

JVM internally maintains the "String Pool". To achive the memory efficiency, JVM will refer the String object from pool. It will not create the new String objects. So, whenever you create a new string literal, JVM will check in the pool whether it already exists or not. If already present in the pool, just give the reference to the same object or create the new object in the pool. There will be many references point to the same String objects, if someone changes the value, it will affect all the references. So, sun decided to make it immutable.

在c++中使用可变字符串的决定会导致很多问题,请参阅Kelvin Henney关于疯牛病的出色文章。

COW =写入时拷贝。

Java中的字符串并不是真正不可变的,您可以使用反射和或类加载来更改它们的值。你不应该依赖这个属性来保证安全。 有关示例请参见:Java中的魔术