技术开发 频道

Groovy 1.6的新特性

  @Delegate

  Java没有提供内置的代理机制,而到目前为止Groovy也没有提供。但借助于@Delegate,我们可以为类的属性加上注解使之成为接收方法调用的代理对象。在下面的示例中,Event类有个date代理,这样编译器就会将Event类上所有的Date方法调用代理给Date。如最后的assert所示,Event类拥有了before(Date)方法及Date的所有方法。

1 import java.text.SimpleDateFormat
2
3   class Event {
4
5   @Delegate Date when
6
7   String title, url
8
9   }
10
11   def df = new SimpleDateFormat("yyyy/MM/dd")
12
13   def gr8conf = new Event(title: "GR8 Conference",
14
15   url: "http://www.gr8conf.org",
16
17   when: df.parse("2009/05/18"))
18
19   def javaOne = new Event(title: "JavaOne",
20
21   url: "http://java.sun.com/javaone/",
22
23   when: df.parse("2009/06/02"))
24
25   assert gr8conf.before(javaOne.when)
26

  Groovy编译器将Date的所有方法加到了Event类中,这些方法仅仅是将调用代理给Date对象。如果代理不是final类,我们甚至还可以通过继承Date使得Event类成为Date的子类,如下所示。要想实现代理,我们无需将Date的所有方法和属性手动加到Event类中,因为编译器会帮我们处理这些事情。

1 class Event extends Date {
2
3   @Delegate Date when
4
5   String title, url
6
7   }
8

  假如要代理某个接口,那么你都无需显式实现该接口。@Delegate负责处理这些并实现该接口,这样,你的类的实例就自动成为代理的接口的实例了(instanceof )。

1 import java.util.concurrent.locks.*
2
3   class LockableList {
4
5   @Delegate private List list = []
6
7   @Delegate private Lock lock = new ReentrantLock()
8
9   }
10
11   def list = new LockableList()
12
13   list.lock()
14
15   try {
16
17   list << 'Groovy'
18
19   list << 'Grails'
20
21   list << 'Griffon'
22
23   } finally {
24
25   list.unlock()
26
27   }
28
29   assert list.size() == 3
30
31   assert list instanceof Lock
32
33   assert list instanceof List
34

  在该示例中,LockableList包含了一个list和一个lock,这样它就instanceof List和Lock了。如果不想让类实现这些接口,那么你可以通过指定注解参数来做到这一点:

  @Delegate(interfaces = false) private List list = []

1