The Play! framework generates getters and setters for each public field of a model class at runtime.
public class Product {
public String name;
public Integer price;
}
will be transformed to
public class Product {
public String name;
public Integer price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
}
The manual explains further:
Then when you want to access a property you can just write:
product.name = "My product";
product.price = 58;
Which is translated at load time to:
product.setName("My product");
product.setPrice(58);
... and warns:
You can’t directly use getter and setter methods to access properties if you rely on automatic generation. These methods are generated at runtime. So if you reference them in code you write, the compiler won’t find the methods and will generate an error.
Since I cannot use these getters and setters from outside of the Play! project, I see no benefit in gen开发者_运维知识库erating them. What is the benefit compared to public fields, refactorings (encapsulate a field and change the callers) of all modern IDEs taken into account?
Short answer: Beans require them.
Longer: Beans specification requires (amongst other things) getter/setter for each internal field. I'm not 100% sure, but I assume both Hibernate and Groovy templates expect Java Beans (the POJO Beans, not the Java EE one!), thus they'll ask for getters/setters. Play just saves you time doing that, so you don't have to worry with boiler-plate code (unless you want to define your own getter/setter for some reason, which you can do).
Another reason,, is although you don't have to specify the setters and getters, you still can!
So, if you have (per your example)
product.name = "my product"
That's fine, and makes your code quicker and in my opinion easier to read. However, there is a good reason for setters and getters for encapsulation. If you wanted to add some logic when your product.name is changed, you can specify your own setter, but you don't have to change the code above, as it will continue to call the setter behind the scenes.
So, this gives you the flexibility and power of good encapsulation, but the neatness and readability of direct field access.
I my opinion this is the best of both worlds.
If you have a private getter/setter method, then this will not work as it is not possible to create a public getter/setter method with same name. So it will fail at run time!
精彩评论