在运行时使对象不可变

时间:2014-01-13 12:14:08

标签: groovy

Groovy中是否可以在运行时使对象不可变?我知道有不可变的注释,但这只是允许你使用构造函数创建对象,然后永远不会更改它。我想要一些东西,我可以创建一个对象调用3或4个方法,然后使它不可变,以便它永远不会再被更改?

关于如何做到这一点的任何想法?

感谢。

2 个答案:

答案 0 :(得分:3)

我不相信你可以。您可以通过元类删除setter,但是您很难将字段设置为final,并且需要将集合更改为不可变变体。

从Groovy 2.2.1开始,copyWith增加了Immutable ......也许这有用吗?

import groovy.transform.*

@Immutable( copyWith=true )
class Test {
    String name
    int age
    List likes
}

def alice = new Test( 'alice', 26, [ 'cheese' ] )
tim = alice.copyWith( name:'tim', age:32 )
timHam = tim.copyWith( likes:[ 'ham' ] )

assert alice.name == 'alice' && alice.age == 26  && alice.likes == [ 'cheese' ]
assert tim.name == 'tim'     && tim.age == 32    && tim.likes == [ 'cheese' ]
assert timHam.name == 'tim'  && timHam.age == 32 && timHam.likes == [ 'ham' ]

对于Java来说这也是Immutator package看起来很有趣,但是我无法让它在Groovy控制台中运行...如果它在包含等的常规groovy环境中工作,可能值得一看< / p>

答案 1 :(得分:0)

如果你想要一个Immutable对象,并且想要在之前调用某些方法(出于配置目的?),那么查看Builder Effective Java Joshua Bloch (page 11)可能会更好。它是一个类,您可以创建它来配置您的对象,然后获取它的不可变实例。

另外,我已经检查过反射方法,但看起来你不能通过它限制字段访问。