为什么不可变类在 Groovy 中是可变的?

Pav*_*vel 4 groovy immutability

在阅读 Benjamin J. Evans 和 Martijn Verburg 所著的“The Well-Grounded Java Developer”一书时,我在 Groovy 中遇到了以下示例:

class Character {
    private int strength
    private int wisdom
}

def pc = new Character(strength: 10, wisdom: 15)
pc.strength = 18
println "STR [" + pc.strength + "] WIS [" + pc.wisdom + "]"
Run Code Online (Sandbox Code Playgroud)

代码片段的输出如下:

STR [18] WIS [15]
Run Code Online (Sandbox Code Playgroud)

到现在为止没有任何问题。上面的代码已经用@Immutable注释稍微修改了,正如书中所建议的:

import groovy.transform.*

@Immutable
class Character {
    private int strength
    private int wisdom
}

def pc = new Character(strength: 10, wisdom: 15)

pc.strength = 18

println "STR [" + pc.strength + "] WIS [" + pc.wisdom + "]"
Run Code Online (Sandbox Code Playgroud)

最后一个片段的输出仍然相同:

STR [18] WIS [15]
Run Code Online (Sandbox Code Playgroud)

预期的结果是什么,但不像上面的那个......

为什么不可变类的对象看起来像可变类?Groovy 中的不变性概念是否允许修改类字段?

Rao*_*Rao 6

为了解决您报告的问题很简单,即删除access modifier to fields. 那应该可以解决问题。

import groovy.transform.Immutable
@Immutable
class Character {
    int strength
    int wisdom
}

def pc = new Character(strength: 10, wisdom: 15)

pc.strength = 18

println "STR [" + pc.strength + "] WIS [" + pc.wisdom + "]"
Run Code Online (Sandbox Code Playgroud)

现在,它将引发异常,如下所示:

groovy.lang.ReadOnlyPropertyException:无法设置只读属性:类强度:
Character.setProperty(Script1.groovy)
at Script1.run(Script1.groovy:10)

如果您想了解有关行为不同原因的更多详细信息,请参阅此处