它是不变的类吗?

时间:2011-12-20 11:05:07

标签: java

下面这个类是不可变的吗?

class Immutable {

  private int x;

  Immutable(int value) {
    this.x = value;
  }

  public int getX(){
    return x;
  }
}
  1. 类不是最终的因为没有成员对子类

  2. 可见
  3. 实例变量x不是最终的,因为没有setter方法。

  4. 这个类是否有可能破坏不可变功能的契约而不在此类中添加任何代码?

4 个答案:

答案 0 :(得分:6)

该课程几乎是不可改变的。

但是你仍然可以使用反射来设置变量x的值,因为变量不是final。

答案 1 :(得分:6)

Immutable类是不可变的。

但是,可以声明其实例是可变的Immutable的子类。实际上,防止这种情况的唯一方法是使这个类final ...或使其构造函数成为私有。

您可能会争辩(我会)Immutable的可变子类违反Immutable的合同。


使用反射更改x值的方法违反了规则。 Java规范说,执行此操作的应用程序的行为未指定。 (当然,它打破了JLS所说的允许JIT编译器做出的各种假设。)

明智的开发人员不会做那样的事情,会贬低别人这样做的可能性,并且会说Immutable是不可改变的,尽管理论上可能会有一些疯子会改变它。

答案 2 :(得分:3)

Joshua Bloch在他的“Effective Java”中指出“你应该设计你的类以实现可扩展性或使它们不可扩展”

如果灵活性是您最关心的问题,并且您有充分的理由为继承设计不可变类 - 请将此类保留为非最终类。

如果担心安全问题 - 请将此课程定稿为最终成员字段。这是因为:

  • 可以通过覆盖getter方法扩展非final类以创建可变子类。

  • Java是reflective设计的。正如Belgther所说,可以使用反射来设置成员字段的值。 (无论是私人还是公共)很久以前I used this将我的特定调试器与另一个项目集成。

答案 3 :(得分:0)

是的,在我看来它是不可改变的。

由于您有一个只能在构造函数中设置的私有字段,并且该类中唯一的方法是getter,因此该字段不能再被修改,并且该类可以说是不可变的。