Groovy Goodness: Direct Field Access In (Super) Classes
When we use the property syntax of Groovy to get the value for a property, Groovy will actually try to invoke a get
method for that property if it is available.
So for example if we have the statement user.name
actually user.getName()
is invoked.
If we want to reference a property field directly, so bypassing the get
method, we must place an @
in front of the property field name.
In the previous example we would write user.@name
to get the field value directly.
The same rules apply for setting a value for a property with the Groovy syntax.
If we write user.name = 'mrhaki'
then actually user.setName('mrhaki')
is invoked.
We can use the @
prefix also to set a value without invoking the set
method for that property.
So in our example it would be user.@name = 'mrhaki'
and the setName
method is not used.
In the following example we have a class Person
with a name
property.
We add a getName
method which formats the name
field and returns the value.
In a subclass User
we access the name
property from the super class using the Groovy property syntax and with the @
prefix:
class Person {
// We must not leave out a modifier,
// because without a modifier,
// Groovy would add
// a getName and setName method if
// they are not already available.
// But Groovy also adds a private modifier
// for this property and being
// private it is not accessible from
// subclasses.
protected String name
String getName() {
"_${name}_"
}
void setName(String name) {
this.name = "*${name}*"
}
}
class User extends Person {
String getUsername() {
// .name will invoke getName().
"User(${this.name})"
}
String getUsernameField() {
// .@name will access name field.
"User(${this.@name})"
}
}
def u = new User(name: 'mrhaki')
assert u.username == 'User(_*mrhaki*_)'
assert u.usernameField == 'User(*mrhaki*)'
assert u.name == '_*mrhaki*_'
assert u.@name == '*mrhaki*'
// Set field value directly
u.@name = 'mrhaki'
assert u.username == 'User(_mrhaki_)'
assert u.usernameField == 'User(mrhaki)'
assert u.name == '_mrhaki_'
assert u.@name == 'mrhaki'
Written with Groovy 2.4.7.