I want to know if there might be use cases where public fields are justified (for mutable values) or it should be avoided at all costs and getters/setters should be always used.
Supposed there is a DTO(Data Transfer Object)/Java Bean which does no have any logic, just holding data (to add more this might part of a protocol which does not change, only enhance). There are effectively no implementation details that exist to be encapsulated because there is no implementation, just data. Also suppose Bean Validation framework is used for validating the object via annotations so there is no purpose of having setters for validating logic.
Why would the setters and getters bother me?
It's more easy to read without setters/getters; fields, especially for inner classes (you don't have to scroll through to setters and getters to reach the other fields). Also it's more clear to have user.password
rather than user.getPassword()
as in Groovy.
I know about project Lombok; but I already have lots of annotations from Bean Validation.
So to make the question clear: might the above scenario be justified for public fields or is it still better to have setters/getters? And why?
The current opinion is that you should not have mutable public fields.
It derives from the Principle of least astonishment from two different directions.
First, it is common practice to have all fields private with access only via getters and setters. There is so much code out there that does this it is surprising when you come across code that doesn't.
Second, it gives you predictability. You can guarantee that no-one will change the fields anywhere else other than in your setter. You can therefore put a break-point on the setter and know that every change to that field will hit the break-point.
There are - however - pure data situations like you describe where it is tempting to make the fields public, and even rarer, not final.
I have in my toolbox a class Pair
which has public fields:
public class Pair<P, Q> {
// Exposing p & q directly for simplicity. They are final so this is safe.
public final P p;
public final Q q;
public Pair(P p, Q q) {
this.p = p;
this.q = q;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With