根据许多文档,我已经看到不可变的类应具有以下功能:

  • 类应该是最终的
  • 所有方法都应该是最终的
  • 所有变量应为最终
  • 应该没有任何二传手

  • 但是我的问题是:
  • 如果我有一个仅带有最终变量的类怎么办?
  • 如果我也有设置器,我将拥有所有最终变量,因此无法更改对象的状态。那么这将如何影响不变性?
  • 在这种情况下,继承如何更改对象状态?
  • 最佳答案

    1.如果我有一个只包含final变量的类怎么办?

    那会让您走得更远,但并非一路走来。这些变量的类型也必须是不可变的。考虑一下

    class MyImmutableClass {
        // final variable, referring to a mutable type
        final String[] arr = { "hello" };
    
        // ...
    }
    

    这允许某人做
    myImmutableObject.arr[0] = "world";
    

    并有效地改变您不变类的对象。

    另外,建议禁止扩展类(因为没有办法强制子类是不可变的)。请参阅下面第三个问题的答案。


  • 如果我也有设置器,我将无法更改对象的状态,因为我拥有所有最终变量。那么这将如何影响不变性。


  • 那就对了。如果所有变量都是最终变量,则标准的setter方法将不存在。


  • 在这种情况下继承如何更改对象状态?


  • 子类无法更改超类的最终字段的状态。但是继承还有另一个问题。

    如果您有一个由Animal子类化的不可变Dog,并且Dog具有使该对象变异的setDogsName方法,那么实际上,您可能具有实际上可变的Animal对象(Dog类型)。

    换句话说,如果打开一个不可变的类进行扩展,则不可变的大多数(全部?)好处会丢失:例如,如果您收到Animal作为方法的参数,则不能认为它是不可变的。您不能安全地将Animal对象作为哈希映射等中的键。

    基本上,原始语句有点多余,这就是为什么我认为它们有点混乱:
  • 不能扩展final类,因此将方法标记为final
  • 也是多余的
  • 如果所有变量都是final,那么说不应该使用setter就是多余的。

  • 同样,这些是足够的约束,但不是必需的。例如,您可以拥有不带最终变量/最终字段类型的不可变类,只要它们是私有的,永不内部更改且永不泄露给外部人员即可。

    10-08 08:18
    查看更多