String如何实现不变性?

时间:2013-02-11 13:49:44

标签: java

在一次采访中,我被问到'字符串是如何变成不可变的?' 由于我不确定答案,我没有回复。我后来问过面试官这个问题。答案是String类是最终的,它是如何实现不变性的。

这是正确的答案吗?如果是,甚至StringBuffer也被标记为最终类。那么为什么StringBuffer不是不可变的呢?

7 个答案:

答案 0 :(得分:11)

它是:

的组合
  1. 字段是私有的 - 因此您无法直接更改它们。
  2. 未提供set个方法 - 因此也无法间接更改。
  3. Stringfinal - 因此您无法为其添加可变性(即设置者等)。

答案 1 :(得分:4)

不,这不是正确的答案。 String实现了不变性,因为它不提供任何方法来更改其内部内容。因此,您可以实例化String对象,为其指定引用,但 一旦初始化就不能更改其内容。

答案 2 :(得分:3)

String是不可变对象。

遵循以下准则使类不可变:

  • 确保无法覆盖课程
  • 制作类final,或使用静态工厂并将构造函数保持为私有
  • 制作字段privatefinal
  • 不提供任何可以以任何方式改变对象状态的方法 - 不只是setXXX方法,而是任何可以改变状态的方法 如果类有任何可变对象字段,那么在类和调用者之间传递它们时必须进行防御性复制
  • 强制调用者在一个步骤中完全构造一个对象,而不是使用无参构造函数与后续调用setXXX方法相结合(即避免使用Java Beans约定)

答案 3 :(得分:2)

final关键字与不变性不同。 String是不可变的,因为它没有定义允许用户更改其内容的任何方法它是最终的,从而消除了更改子类中的内容的可能性。

制作类似List实例变量final的内容仍然允许您更改其内容,使其可变。

答案 4 :(得分:1)

最终意味着它无法从中衍生出来。这并不能赋予不变性

通过封装实现不变性,并且不提供任何修改内部保持字符数组的方法。即没有方法可以修改内部字段。

答案 5 :(得分:0)

字符串池(最初为空)由String类私有维护。

你应该看看String的JavaDoc: public native String intern();

请参阅:

答案 6 :(得分:0)

使类不可变的通常方法是确保:

  • 所有字段都是私密的;
  • 施工后无法修改字段;
  • 它是最终的(因此扩展不能破坏不变性)。

字符串有点特殊,至少在Sun / Oracle实现中, 实际上不遵循此过程。该实现具有可变字段,其中它缓存对象的哈希码。因此,虽然有一种方法可以更改对象的内部状态(hashCode),但此状态更改不会以任何方式更改对象的行为。对hashCode的任何后续调用都会运行得更快,但结果不会有任何不同。