04.07.2013 Views

Programming Grails - Cdn.oreilly.com

Programming Grails - Cdn.oreilly.com

Programming Grails - Cdn.oreilly.com

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

You’ve already seen how property access and the <strong>com</strong>pact syntax for collections and<br />

maps can help condense your code, but there are a lot more ways.<br />

Constructors<br />

It’s rare to see constructors in Groovy classes. This is because the Groovy <strong>com</strong>piler adds<br />

a constructor that takes a Map and sets field values to map values where the key corre‐<br />

sponds to a field name. This gives you named parameters for this constructor syntax,<br />

so it’s both more convenient and clearer which values are which. For example, a simple<br />

POGO like this:<br />

class Person {<br />

String firstName<br />

String initial<br />

String lastName<br />

Integer age<br />

}<br />

can be constructed by setting some or all of the field values:<br />

def author = new Person(firstName: 'Hunter', initial: 's', lastName: 'Thompson')<br />

def illustrator = new Person(firstName: 'Ralph', lastName: 'Steadman', age: 76)<br />

def someoneElse = new Person()<br />

In the examples, I’m taking advantage of Groovy letting me omit the [ and ] map<br />

characters, because it makes the invocations cleaner.<br />

This is especially useful for classes with many fields; in Java, you have to either define<br />

multiple constructors with various signatures or pass lots of nulls where you don’t have<br />

a value.<br />

However, note that the Map constructor relies on the default constructor that’s added to<br />

all classes that don’t define any explicit constructors. It calls that constructor, then sets<br />

properties from the provided Map (this is defined in MetaClassImpl.invokeConstruc<br />

tor(), if you’re curious). But if you declare one or more parameterized constructors,<br />

the <strong>com</strong>piler doesn’t generate an empty one for you, and the Map constructor will fail.<br />

Also, because it’s not a real constructor that’s added to the bytecode, you can use this<br />

with Java classes that have a default constructor, too. So you could replace this code:<br />

MutablePropertyValues propertyValues = ...<br />

def beanDef = new GenericBeanDefinition()<br />

beanDef.setBeanClassName('<strong>com</strong>.foo.bar.ClassName')<br />

beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)<br />

beanDef.setPropertyValues(propertyValues)<br />

with this:<br />

MutablePropertyValues propertyValues = ...<br />

def beanDef = new GenericBeanDefinition(<br />

beanClassName: '<strong>com</strong>.foo.bar.ClassName',<br />

14 | Chapter 1: Introduction to Groovy

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!