@Immutable
不变对象意指创建后无法改变的对象。人们经常需要这类对象,因为他们够简单并且可以在多线程环境下安全的共享。鉴于此,他们非常适合于功能性和并发性场景。创建此类对象的规则是众所周知的:
无存取器(即可以修改内部状态的方法)
类必须为final的
属性必须为private和final的
可变组件的保护性拷贝(defensive copying)
如果想要比较对象或是将其作为Map等的键时需要根据属性来实现equals()、hashCode()及toString()
你无需根据上面这些原则编写长长的Java或Groovy类,Groovy可以按照下面的方式来定义一个不变的类:
1 @Immutable final class Coordinates {
2
3 Double latitude, longitude
4
5 }
6
7 def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)
8
9 def c2 = new Coordinates(48.824068, 2.531733)
10
11 assert c1 == c2
2
3 Double latitude, longitude
4
5 }
6
7 def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)
8
9 def c2 = new Coordinates(48.824068, 2.531733)
10
11 assert c1 == c2
所有的样板式代码(boiler-plate code)都在编译期生成!你可以使用其所创建的两个构造方法来实例化不变的Coordinates对象,第一个构造方法接收一个Map,其键就是相应的属性,后跟其值;第二个构造方法的参数为属性值。assert表明equals()方法已被实现,我们可以正确的比较这些不变对象。
如果有兴趣可以看看该转换器的实现细节。上面使用了@Immutable的Groovy代码示例相当于50多行Java代码。