我有一个groovy类 - 它的一半属性总是不可变的(并在构造期间设置),另一半是可变的。
有什么办法可以在Groovy中标记它吗?
答案 0 :(得分:5)
在可变性或不变性方面,没有灰色阴影。
它有点像食物:"我有一个不可食用和半食用的汉堡......"
一种选择是将不可变部分提取到Immutable类,然后委托给你的可变部分,即:
import groovy.transform.*
@Immutable
class Point {
int x, y
}
@Canonical
class Pixel {
int color
@Delegate Point point
}
Pixel p = new Pixel( 0xFF0000, new Point( 10, 10 ) )
assert p == new Pixel( 0xFF0000, new Point( 10, 10 ) )
// Change the mutable color
p.color = 0x00FF00
assert p == new Pixel( 0x00FF00, new Point( 10, 10 ) )
// Change the point (can be done as Pixel is mutable)
p.point = new Point( 10, 20 )
assert p == new Pixel( 0x00FF00, new Point( 10, 20 ) )
// Cannot change the Point properties
try {
p.point.x = 20
assert false
}
catch( e ) {
assert e.class == ReadOnlyPropertyException
}
或者,如果可以使整个事物成为不可变的,您可以使用copyWith
方法生成新的像素:
import groovy.transform.*
@Immutable
class Point {
int x, y
}
@Immutable( copyWith=true )
class Pixel {
int color
@Delegate Point point
}
Pixel p = new Pixel( 0xFF0000, new Point( 10, 10 ) )
assert p == new Pixel( 0xFF0000, new Point( 10, 10 ) )
// Make a new copy with a new color
p = p.copyWith( color:0x00FF00 )
assert p == new Pixel( 0x00FF00, new Point( 10, 10 ) )
// Make a new copy with a new point
p = p.copyWith( point:new Point( 10, 20 ) )
assert p == new Pixel( 0x00FF00, new Point( 10, 20 ) )
// Cannot change the Point properties directly
try { p.point.x = 20 ; assert false }
catch( e ) { assert e.class == ReadOnlyPropertyException }
// or
try { p.color = 0x0000FF ; assert false }
catch( e ) { assert e.class == ReadOnlyPropertyException }