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

标签 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 + "]"

代码片段的输出如下:
STR [18] WIS [15]

到现在为止没有任何问题。上面的代码已经用 @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 + "]"

最后一个片段的输出仍然相同:
STR [18] WIS [15]

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

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

最佳答案

为了解决您报告的问题很简单,即删除 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 + "]"

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

groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: strength for class: Character
at Character.setProperty(Script1.groovy)
at Script1.run(Script1.groovy:10)



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

关于groovy - 为什么不可变类在 Groovy 中是可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44449224/

相关文章:

java - 有什么方法可以区分一个类是来自 Groovy/Grails 还是原始 Java?

string - Go 中的不可变字符串

gradle - grails 3 cobertura没有显示线覆盖率

grails - 从YAML通过关联加载GORM

windows - 如何以与 "cmd/c <command>".execute() 相同的方式从 groovy 运行 PowerShell 命令?

jenkins - 使用 hudson 的管道插件获取内联管道脚本中的当前时间戳

android - 可变的 android.os.Environment.DIRECTORY_WHATEVER?

javascript - 在javascript中创建不可变对象(immutable对象)

c# - C++ 字符串与 C# 字符串,不同的运行时间。为什么?

java - 安全发布以及不可变与有效不可变的优势