所有最终类都是不可变的吗?

Gou*_*rav 14 java immutability

Java中的所有最终类都是不可变的.String和Integer都是最终类,两者都是不可变的.

Mic*_*mlk 30

不,最终意味着课程无法延期.它没有说明可变性.例如:

final class MutInt {
   public int modifyMe;
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*itz 22

不 - 最后一堂课意味着你不能从中继承.它与可变性无关.以下类是最终的可变的:

public final class FinalMutable {
  int value;
  public void setValue(int v) { value=v; }
  public int getValue() { return value; }
}
Run Code Online (Sandbox Code Playgroud)

  • 因此,为了使类不可变,我必须从类中删除setter()方法,并使其实例变量(在本例中为"value")为final.我对么..?? (2认同)

Tim*_*the 9

不可变性没有关键字,它更像是一种设计模式.

编辑:
这意味着,没有关键字,使一个类不可变.要使类不可变,您必须通过将它们设为final或private来保护内部.

令人困惑的是:final关键字在类上使用时具有不同的含义,然后在字段/变量上使用时具有不同的含义.前者的意思是"这个课程不能延长".第二个意思是"这个变量(或参考)不能改变".

  • 字段和变量有"final"关键字 - 但是,它不会使对象成为不可变的,只是引用. (3认同)

Ada*_*ski 5

除了其他响应之外,如果您查看代码,java.lang.String您将看到它包含一个字段:hash,它是可变的,实际上hashCode()是在第一次调用时计算和存储.

但是,该类仍然是不可变的:该hash字段不能直接访问或在类外修改.

此外,您可能会注意到JDK中的一个常见方法是实现不可变包装器,这些包装器可用于公开对象的内部状态而不允许对其进行修改; 例如

private final List<String> values;

public List<? get String> getValues() {
  return Collections.unmodifiableList(values);
}
Run Code Online (Sandbox Code Playgroud)


non*_*tor 5

正如其他人之前所说的final那样,虽然它在不变性策略中起作用,但它并没有使Java成为一个可用的类.要获得不变性,您应该遵循一般指导原则:

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