@Lazy
另一个转换就是@Lazy。有时你想延迟加载某些属性,即只在第一次使用时才会进行处理,这通常发生在处理时间长、内存消耗大的情况下。通常的解决办法是对这种字段的getter进行特殊的处理以在首次调用时完成初始化。但在Groovy 1.6中,我们可以使用@Lazy注解实现该目的:
1 class Person {
2
3 @Lazy pets = ['Cat', 'Dog', 'Bird']
4
5 }
6
7 def p = new Person()
8
9 assert !(p.dump().contains('Cat'))
10
11 assert p.pets.size() == 3
12
13 assert p.dump().contains('Cat')
14
2
3 @Lazy pets = ['Cat', 'Dog', 'Bird']
4
5 }
6
7 def p = new Person()
8
9 assert !(p.dump().contains('Cat'))
10
11 assert p.pets.size() == 3
12
13 assert p.dump().contains('Cat')
14
如果字段初始化需要复杂的计算,那么你需要调用某些方法而不是直接使用值(像下面的pets列表)来实现。接下来就可以通过闭包调用完成延迟赋值了,如下所示:
1 class Person {
2
3 @Lazy List pets = { /* complex computation here */ }()
4
5 }
6
2
3 @Lazy List pets = { /* complex computation here */ }()
4
5 }
6
我们还可以对包含延迟字段的复杂数据结构使用适合垃圾收集器的软引用(Soft reference):
1 class Person {
2
3 @Lazy(soft = true) List pets = ['Cat', 'Dog', 'Bird']
4
5 }
6
7 def p = new Person()
8
9 assert p.pets.contains('Cat')
10
2
3 @Lazy(soft = true) List pets = ['Cat', 'Dog', 'Bird']
4
5 }
6
7 def p = new Person()
8
9 assert p.pets.contains('Cat')
10
编译器为pets所创建的内部字段实际上是个软引用,但访问p.pets会直接返回该引用所持有的值(也就是pets列表),这样软引用对于类的用户来说就是透明的了。