【问题标题】:How does @Immutable work in groovy?@Immutable 如何在 groovy 中工作?
【发布时间】:2014-09-02 04:04:56
【问题描述】:

当我在 groovy 控制台中执行以下代码时,我得到一个 groovy.lang.ReadOnlyPropertyException。正如预期的那样,属性 x 应该无法更改(因为 ClassA 是不可变的)。

import groovy.transform.Immutable
@Immutable class ClassA {
    int x
}

def a = new ClassA(x: 5);
a.x = 1

但是如果将 x 变量的访问修饰符更改为私有,那么我可以在 groovy 控制台中执行此操作:

import groovy.transform.Immutable
@Immutable class ClassA {
    private int x
}

def a = new ClassA(x: 5);
a.x = 1
println(a.x)

这是为什么?为什么添加的private 访问修饰符会使ClassA 可变?

【问题讨论】:

    标签: groovy


    【解决方案1】:

    docs 对此有明确的立场。他们总是谈论“属性”。也有摘录表明,“滚动你自己的”不被视为“状态”:

    您不必遵循 Groovy 的常规属性约定,例如您可以创建一个显式的私有字段,然后您可以编写显式的 get 和 set 方法。这种方法目前不被禁止(给你一些回旋余地来绕过这些约定),但是以这种方式创建的任何字段都被认为不是对象的重要状态的一部分,并且不会被考虑到等式中或 hashCode 方法。

    一个微不足道的指标是,toString 是为这些类创建的。例如:

    @groovy.transform.Immutable
    class A {
        private int a
    }
    
    @groovy.transform.Immutable
    class B {
        int b
    }
    
    a=new A()
    a.a = 42
    println a
    b=new B()
    // b.b = 42
    println b
    

    将打印:

    A()
    B(0)
    

    表明,A.@a 不是不变性“计算”(“重要状态”)的一部分。由于您可以在 groovy 中访问私有变量,因此您上面的代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 2016-02-19
      • 2019-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      相关资源
      最近更新 更多