@Immutable如何在groovy中工作?

etx*_*lpo 6 groovy

当我在groovy控制台中执行以下代码时,我得到了一个groovy.lang.ReadOnlyPropertyException.这是预期的,因为属性x不应该可以改变(因为它ClassA是不可变的).

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

def a = new ClassA(x: 5);
a.x = 1
Run Code Online (Sandbox Code Playgroud)

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

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

def a = new ClassA(x: 5);
a.x = 1
println(a.x)
Run Code Online (Sandbox Code Playgroud)

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

cfr*_*ick 8

文件对此有明确的立场.他们总是谈论"财产".也有exerpts指出,"滚动你自己"不被视为"状态":

您不必遵循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
Run Code Online (Sandbox Code Playgroud)

将打印:

A()
B(0)
Run Code Online (Sandbox Code Playgroud)

显示,这A.@a不是不可变性"计算"的一部分("重要国家").并且您可以在groovy中访问私有变量,上面的代码工作得很好.