Close

Groovy - Automatic JavaBean properties

[Last Updated: Aug 11, 2020]

In Groovy the class fields become automatic properties if no access modifier is used. That is if no access modifiers (public, protected or private) are used, the fields become 'private' and their getters/setters are automatically added to the compile class.

import java.lang.reflect.Modifier

class Person {
    String name;
    int age;
}

//checking field visibility
def modifiers = Person.class.getDeclaredField("name").getModifiers()
println Modifier.toString(modifiers)

//creating an instance
def p = new Person();
p.setName("Tina")
p.setAge(25)
println p.getName()
println p.getAge()


Output

private
Tina
25

Properties' setters can be invoked just like we assign values to the fields (in this example we are adding explicit getters/setters for logging):

class Person {
    String name;
    int age;

    void setName(String name) {
        println "in name setter"
        this.name = name
    }

    String getName() {
        println "in name getter"
        return name
    }

    void setAge(int age) {
        println "in age setter"
        this.age = age
    }

    int getAge() {
        println "in age getter"
        return age
    }
}

def p = new Person();
p.name = "Tina" // will invoke setter
p.age = 25 //will invoke setter
println p.name //will invoke getter
println p.age //will invoke getter


Output

in name setter
in age setter
in name getter
Tina
in age getter
25

Read only Properties

To make a property read only we just need to add 'final' modifier with the field. In that case no setter will be generated.

class Person {
    final String name;
    int age;

    Person(String name) {
        this.name = name
    }
}

def p = new Person("Tina");
p.age = 25
println p.getName()
println p.getAge()


Output

Tina
25

If we try to call setter on final fields:

class Person {
    final String name;
    int age;

    Person(String name) {
        this.name = name
    }
}

def p = new Person("Tina");
p.setName("Diana");
groovy.lang.MissingMethodException: No signature of method: Person.setName() is applicable for argument types: (String) values: [Diana]
Possible solutions: getName(), setAge(int), getAge(), getAt(java.lang.String)
	at Example3AutomaticFinalProperty.run(Example3AutomaticFinalProperty.groovy:11)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

No backing fields

Groovy will recognize properties even if there is no backing field provided and if there are getters or setters that follow the Java Beans specification.

class Person {
    Map<String, Object> map = new HashMap<>();
    //read only
    String getName(){
        return "Tina";
    }
    
    def getAge(){
        return map.get("age")
    }

    void setAge(int age){
        map.put("age", age);
    }

}

def p = new Person();
p.age = 25
println p.age
print p.name

Output

25
Tina

Example Project

Dependencies and Technologies Used:

  • Groovy 2.5.6
  • JDK 9.0.1
Automatic properties in Groovy Select All Download
  • groovy-automatic-properties
    • src
      • Example1AutomaticProperties.groovy

    See Also