为什么他们决定在Java和。net(和其他一些语言)中使字符串不可变?为什么不让它变呢?
当前回答
String不是一个基本类型,但你通常想用值语义来使用它,即像一个值。
价值观是你可以信任的东西,不会在你背后改变。 String str = someExpr(); 你不希望它改变,除非你对str做些什么。
String作为对象自然具有指针语义,为了获得值语义,它也需要是不可变的。
其他回答
在c++中使用可变字符串的决定会导致很多问题,请参阅Kelvin Henney关于疯牛病的出色文章。
COW =写入时拷贝。
String不是一个基本类型,但你通常想用值语义来使用它,即像一个值。
价值观是你可以信任的东西,不会在你背后改变。 String str = someExpr(); 你不希望它改变,除非你对str做些什么。
String作为对象自然具有指针语义,为了获得值语义,它也需要是不可变的。
人们应该问,“为什么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 [...]
同一章的其他要点:
不仅可以共享不可变对象,还可以共享它们的内部结构。 […] 不可变对象为其他对象提供了很好的构建块,无论是可变的还是不可变的。 […] 不可变类的唯一缺点是,它们需要为每个不同的值提供一个单独的对象。
推荐文章
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- Printf与std::字符串?
- AppSettings从.config文件中获取值
- 在Jar文件中运行类
- 带参数的可运行?
- 如何检查IEnumerable是否为空或空?
- 不区分大小写的“in”
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 我可以在Java中设置enum起始值吗?