Skip to end of metadata
Go to start of metadata

GroovyBeans 就是 JavaBeans,不过它的语法非常简单。
示例:

注意属性如何像公开域那样使用。(Notice how the properties look just like public fields.)在 Groovy 中,还可以在构造方法是设置具名的属性值。在 Groovy 中属性(properties)和域(fields)合并了,使用起来是一样的。下面的 Java 代码和上面的 Groovy 代码是等价的:

属性和域的规则(Property and field rules)

Icon

还不太理解这里所说的域(Field)和属性(Properties),一直把它们当作相似的概念。这里域似乎是指定义的变量,而属性是变量的访问方法(getter/setter)。所以这部分翻译可能不太准确,最好参考原文。

当 Groovy 被编译成字节码时,会遵循以下规则:

  • 如果变量名声明时使用了访问限定符(公开的 public、私有的 private 或 受保护的 protected),那么生成一个域(field)。
  • 没有使用限定符的声明的变量名会生成一个私有域和相应的公开的 setter 和 getter,也就是生成一个属性(property)。
  • 如果属性声明为 final,生成一个私有的 final 域,不生成 setter。
  • 你可以自己声明一个属性和相关的 getter、setter。
  • 属性和域可以同名,不过属性会使用域来操作。
  • 如果想用一个私有的或受保护的属性,你必须自己写 getter 和 setter,而且它们要声名为 private 或 protected。
  • 如果你在定义属性的类中隐或或显式的使用 this 访问属性(例如 this.foo,或者直接写 foo),Groovy 会直接访问域,而不是通过 getter 和 setter。
  • 如果你访问不一个不存在的属性,Groovy 会通过元类(meta class)来访问,这在运行时可能会出错。

因此,你可以像这下面这样用一个受保护的 setter 来实现一个只读的属性:

注意属性需要使用一些标识:例如类型(“String”)或者使用“def”表示它未定义类型。

为什么没有为公开的域没有生成 getter 和 setter 呢?如果我们总是生成 getter / setter,也就是说 Groovy 不允许不定义 getters / setters,这在你不想暴露 getter / setter 时就有问题了。

闭包和监听器(Closures and listeners)

尽管 Groovy 不支持匿名内部类,还是有办法通过闭包来定义动作监听器(action listeners)的。所以不像用 Java:

在 Groovy 中你可以使用闭包:

注意是如何将闭包添加到监听器接口 方法 (controllerUpdate)上,而 —不是添加到接口本身 (ControllerListener)的。这个技术意味着 Groovy 的监听器闭包使用起来像一个监听适配器(ListenerAdapter),只有一个可被重载的方法。注意:如果重载的方法名拼写错误或者直接使用接口(而不是方法),这种错误很难发现,因为 Groovy 的语法分析器可能会把它当作属性赋值而不认为它是事件监听器的闭包。

这种机制在 Swing 中经常使用,为不同的组件定义事件监听器。JavaBeans introspector 能把事件监听器转换为属性,这样就可以赋值一个闭包了。(JavaBeans introspector The is used to make event listener methods available as properties which can be set with a closure.)

Java Beans introspector(java.beans.Introspector)可以查找或者用它的命名转换创建一个 BeanInfo。(如果你不使用自己的 BeanInfo,可以在 Java Beans 规格说明中看一下它用的命名转换。)我们不执行任何命名转换-标准的 Java Bean introspector 会为我们处理的。

基本上 BeanInfo 是从 bean 获得的,并且它的 EventSetDescriptors 是作为属性暴露出来的(假设它和普通的 bean 没有冲突)。实际上它就是 EventSetDescriptor.getListenerMethods(),它是作为一个可写的属性暴露出来的,这样就可以将闭包赋值给它了。

  • No labels