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()
Outputprivate 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
Outputin 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()
OutputTina 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
Output25 Tina
Example ProjectDependencies and Technologies Used: |