2

为什么这个String类的设计方式是这个类的实例是池化的并且是不可变的?

谢谢和问候,维迪亚卡尔夏尔马。

4

5 回答 5

6

字符串对象通常不被池化——只有字符串常量通过实习自动池化。(当然,您可以intern手动调用,甚至通过HashSet<String>等方式创建自己的池。)这只是安全的,因为字符串是不可变的 - 确保任何编译时常量只在内存中出现一次是有意义的。

您不希望为系统中的每个字符串在实习生池中查找字符串(或永远保留它)付出代价,因为随着时间的推移可能会有许多不同的字符串。但是,从类加载的字符串常量会一直存在,只要这些类存在,并且通过将它们实习一次可以减少 GC 流失所需的内存。

于 2011-09-14T14:57:31.947 回答
3

如果 String 不是不可变的,您将无法

  • 在不破坏封装的情况下从 getter 安全地返回 String 字段,因为调用者可能会在你背后修改字符串的内容
  • 在线程之间共享字符串,因为某些线程可能会修改其内容。对 String 的所有访问都必须同步。
  • 在 HashMaps/TreeMaps 中使用字符串作为键,因为有人可能会更改其值,从而更改其 hashCode/比较顺序
  • 池化字符串以便拥有相同常量字符串的单个实例
  • 让子字符串共享其字符串的相同 char 数组

简而言之,生活会复杂得多,因为您必须在各处制作 String 的防御性副本,并且 StackOverflow 将充斥着关于一些 String 存储在地图中但无法再找到的细微错误的问题。

于 2011-09-14T15:10:26.117 回答
2

不可变对象是现有的最佳设计决策之一。它旨在简化并发编程。共享对象的线程不能互相干扰。

如果您想要可变字符串,请查看:StringBufferStringBuilder

于 2011-09-14T14:58:53.337 回答
1

对于可变字符串,请查看:来自 java.lang 的 StringBuffer 和 StringBuilder。

于 2011-09-14T15:33:11.647 回答
0

池化以避免具有表示相同的重复对象。

不可变以使其更易于共享。

于 2011-09-14T14:56:38.813 回答