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


当前回答

一个因素是,如果字符串是可变的,那么存储字符串的对象必须小心地存储副本,以免它们的内部数据在没有通知的情况下发生变化。鉴于字符串是一种相当基本的类型,就像数字一样,即使它们是通过引用传递的,也可以把它们当作是按值传递的,这是很好的(这也有助于节省内存)。

其他回答

人们应该问,“为什么X应该是可变的?”最好默认为不可变,因为Princess Fluff已经提到了它的好处。它应该是一个例外,某些东西是可变的。

不幸的是,目前大多数编程语言都默认为可变性,但希望未来的默认更多地是不变性(参见下一个主流编程语言的愿望清单)。

根据Effective Java,第4章,第73页,第二版:

"There are many good reasons for this: Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure. [...] "Immutable objects are simple. An immutable object can be in exactly one state, the state in which it was created. If you make sure that all constructors establish class invariants, then it is guaranteed that these invariants will remain true for all time, with no effort on your part. [...] Immutable objects are inherently thread-safe; they require no synchronization. They cannot be corrupted by multiple threads accessing them concurrently. This is far and away the easiest approach to achieving thread safety. In fact, no thread can ever observe any effect of another thread on an immutable object. Therefore, immutable objects can be shared freely [...]

同一章的其他要点:

不仅可以共享不可变对象,还可以共享它们的内部结构。 […] 不可变对象为其他对象提供了很好的构建块,无论是可变的还是不可变的。 […] 不可变类的唯一缺点是,它们需要为每个不同的值提供一个单独的对象。

String不是一个基本类型,但你通常想用值语义来使用它,即像一个值。

价值观是你可以信任的东西,不会在你背后改变。 String str = someExpr(); 你不希望它改变,除非你对str做些什么。

String作为对象自然具有指针语义,为了获得值语义,它也需要是不可变的。

这是一种权衡。字符串进入String池,当您创建多个相同的字符串时,它们共享相同的内存。设计人员认为这种节省内存的技术在一般情况下会很好地工作,因为程序倾向于反复处理相同的字符串。

缺点是连接产生了许多额外的字符串,这些字符串只是过渡性的,只是垃圾,实际上会损害内存性能。在这些情况下,可以使用StringBuffer和StringBuilder(在Java中,。net中也有StringBuilder)来保存内存。

至少有两个原因。

第一-安全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.