GroovyBeans are JavaBeans but using a much simpler syntax.
Here's an example:
Notice how the properties look just like public fields. You can also set named properties in a bean constructor in Groovy. In Groovy, fields and properties have been merged so that they act and look the same. So, the Groovy code above is equivalent to the following Java code:
Property and field rules
When Groovy is compiled to bytecode, the following rules are used.
- If the name is declared with an access modifier (public, private or protected) then a field is generated.
- A name declared with no access modifier generates a private field with public getter and setter (i.e. a property).
- If a property is declared final the private field is created final and no setter is generated.
- You can declare a property and also declare your own getter or setter.
- You can declare a property and a field of the same name, the property will use that field then.
- If you want a private or protected property you have to provide your own getter and setter which must be declared private or protected.
- If you access a property from within the class the property is defined in at compile time with implicit or explicit this (for example this.foo, or simply foo), Groovy will access the field directly instead of going though the getter and setter.
- If you access a property that does not exist using the explicit or implicit foo, then Groovy will access the property through the meta class, which may fail at runtime.
So, for example, you could create a read only property or a public read-only property with a protected setter like this:
Note that properties need some kind of identifier: e.g. a variable type ("String") or untyped using the "def" keyword.
Why a field with public access modifier do not have getter and setter generated? If we'd generate getter / setter all the time, it means Groovy would
not let you not define getters / setters, which can be problematic when you really don't want to geters / setters to be exposed.
Closures and listeners
Though Groovy doesn't support anonymous inner classes, it is possible to define action listeners inline through the means of closures. So instead of writing in Java:
You can do that in Groovy with a closure:
Notice how the closure is for a method on the listener interface (controllerUpdate), and not for the interface itself(ControllerListener). This technique means that Groovy's listener closures are used like a ListenerAdapter where only one method of interest is overridden. Beware: mistakenly misspelling the method name to override or using the interface name instead can be tricky to catch, because Groovy's parser may see this as a property assignment rather than a closure for an event listener.
This mechanism is heavily used in the Swing builder to define event listeners for various components and listeners. The JavaBeans introspector is used to make event listener methods available as properties which can be set with a closure.
The Java Beans introspector (java.beans.Introspector) which will look for a BeanInfo for your bean or create one using its own naming conventions. (See the Java Beans spec for details of the naming conventions it uses if you don't provide your own BeanInfo class). We're not performing any naming conventions ourselves - the standard Java Bean introspector does that for us.
Basically the BeanInfo is retrieved for a bean and its EventSetDescriptors are exposed as properties (assuming there is no clash with regular beans). It's actually the EventSetDescriptor.getListenerMethods() which is exposed as a writable property which can be assigned to a closure.