简体   繁体   English

String如何实现不变性?

[英]How String achieves immutability?

In one of the interview I was asked 'How String is made immutable?' 在其中一次采访中,我被问到“字符串是如何变为不可变的”? As i wasnot sure about the answer, i didnot reply. 由于我不确定答案,我没有回复。 I asked the interviewer later regarding the same. 我后来问过面试官这个问题。 Answer was String class is final that's how immutability is achieved. 答案是String类是最终的,它是如何实现不变性的。

Is that the correct answer? 这是正确的答案吗? if yes, even StringBuffer is also marked as final class. 如果是,甚至StringBuffer也被标记为最终类。 Then why not StringBuffer is immutable? 那为什么StringBuffer不可变?

It is a combination of: 它是以下组合:

  1. Fields are private - so you cannot change them directly. 字段是私有的 - 因此您无法直接更改它们。
  2. No set methods provided - so they cannot be changed indirectly either. 没有提供set方法 - 因此它们也不能间接改变。
  3. String is final - so you cannot add mutability (ie setters etc.) to it. Stringfinal - 所以你不能添加可变性(即setter等)。

No that's not the correct answer. 不,这不是正确的答案。 String achieves immutability because it doesn't provide you any method to change its internal contents. String实现了不变性,因为它不提供任何方法来更改其内部内容。 Thus you can instantiate a String object, assign a reference to it but cannot change its contents once initialized. 因此,您可以实例化String对象,为其指定引用,但在初始化后不能更改其内容。

String is immutable object. 字符串是不可变对象。

Make a class immutable by following these guidelines : 按照以下准则使类不可变:

  • ensure the class cannot be overridden 确保不能覆盖类
  • make the class final , or use static factories and keep constructors private 使类final ,或使用静态工厂并保持构造函数私有
  • make fields private and final 将字段设为privatefinal
  • do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state if the class has any mutable object fields, then they must be defensively copied when passed between the class and its caller 不提供任何可以以任何方式改变对象状态的方法 - 不仅仅是setXXX方法,而是任何可以在类具有任何可变对象字段时改变状态的方法,那么它们必须在类之间传递时进行防御性复制。它的来电者
  • force callers to construct an object completely in a single step, instead of using a no- argument constructor combined with subsequent calls to setXXX methods (that is, avoid the Java Beans convention) 强制调用者完全在一个步骤中构造一个对象,而不是使用无参数构造函数和后续调用setXXX方法(即避免Java Beans约定)

The final keyword is not the same as immutability. final关键字与immutability不同。 String is immutable as it does not define any methods that allow a user to change its content and it is final, removing the possibility to change things in a subclass. String是不可变的,因为它没有定义允许用户更改其内容的任何方法, 并且它是最终的,从而消除了更改子类中的内容的可能性。

Making something like a List instance variable final will still allow you to change its contents, making it mutable. 制作像List实例变量final这样的东西仍然允许你改变它的内容,使它变得可变。

Being final means it can't be derived from. 最终意味着它无法从中衍生出来。 That doesn't confer immutability 这并不能赋予不变性

Immutability is achieved by encapsulation and not providing any means to amend the internally held character array. 通过封装实现不变性,并且不提供任何修改内部保持的字符数组的方法。 Ie no methods exist to modify the internal fields. 即没有方法可以修改内部字段。

A pool of strings, initially empty, is maintained privately by the class String. 最初为空的字符串池由String类私有维护。

You should look at the JavaDoc of String: public native String intern(); 您应该查看String的JavaDoc: public native String intern();

See: 看到:

The usual way to make a class immutable is to ensure that: 使类不可变的通常方法是确保:

  • all the fields are private; 所有的领域都是私人的;
  • there is no way to modify the fields after construction; 施工后无法修改字段;
  • it is final (so that extensions cannot break immutability). 它是最终的(因此扩展不能破坏不变性)。

String is a bit special, at least in the Sun/Oracle implementation in that it does not actually follow this procedure. String是一个有点特殊,在它实际上并不遵循这一程序在Sun / Oracle实施至少。 The implementation has a mutable field in which it caches the hash code of the object. 该实现具有可变字段,其中它缓存对象的哈希码。 So while there is a method that changes the internal state of the object ( hashCode ), this state change does not change the behaviour of the object in any way. 因此,虽然有一个方法可以更改对象的内部状态( hashCode ),但此状态更改不会以任何方式更改对象的行为。 Any subsequent calls to hashCode will run faster, but the result won't be any different. hashCode任何后续调用都会运行得更快,但结果不会有任何不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM