Groovy Tip 8 GroovyBean
做这个主题的时候,我曾想了好些天,要不要做这个主题。因为Groovy Bean对于使用Groovy语言的开发者来说再熟悉不过,说不定每天都在用它。犹豫了好多天,才决定把它写下来。因为我也使用Groovy Bean很久了,但很多概念也是慢慢搞清楚的,在写代码的时候走了一些弯路。
肯定很多使用了Groovy语言的开发者写过类似于这样的代码:
class Person
{
String name
int age
String addr
}
也肯定这样使用过:
Person person = new Person()
person.name = 'Tom'
……
很多初次接触Groovy语言的人都以为Groovy Bean的属性是公开的,可以直接访问。这其实是一个误解。上面的Person类其实相当于如下的Java类:
publicclass Person {
private String name;
privateintage;
private String addr;
public String getAddr() {
returnaddr;
}
publicvoid setAddr(String addr) {
this.addr = addr;
}
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age = age;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
}
因此,上面的person.name = 'Tom'语句其实相当于Java语言中的:
person.setName(“Tom”);
而println person.name语句相当于Java语言中的:
person.getName();
同样,Groovy语言还有一个一个规则,如果你声明一个属性为“private”、“public”或“protected”,那么你只是声明了一个属性,这意味着你要自己写属性的“set”和“get”方法。
Groovy语言对Java语言的Javabean的更外一个简化就是你不需要给Groovy Bean编写一个构造器,就可以使用构造器。如:
Person person = new Person(name:'Tom')
println person.name
当然,你也可以一口气把Person类的属性全部赋值:
Person person = new Person(name:'Tom',age:22,addr:'Shenzhen')
println"${person.name} lived in ${person.addr}"
打印结果为:
Tom lived in Shenzhen
当你把一个属性声明成final的时候,就不能再给该属性赋值了。如:
class Person {
String name
finalint age = 22
String addr
}
它相当于Java的:
publicclass Person {
private String name;
privatefinalintage = 22;
private String addr;
public String getAddr() {
returnaddr;
}
publicvoid setAddr(String addr) {
this.addr = addr;
}
publicint getAge() {
returnage;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
}
注意,只有getAge()方法,没有set方法。
如果你对上面的Groovy Bean进行如下访问:
Person person = new Person(name:'Tom',age:22,addr:'Shenzhen')
println"${person.name} lived in ${person.addr}"
就会抛出如下的Exception:
Exception in thread "main" groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: age for class: Person