Maybe you do this by default if you are developing an external API for versioning reasons but that’s such a niche use case.
I find that getters and setters seem like pointless overhead when I have an idea that I want to test empirically as soon as possible, but if I don't, I end up with a lot of regret years later when I have to track down all the references and update them instead of just changing code in the one place.
I'm not a fan of lazy loading, but I know a lot of people are, and using the getter/setter pattern also enables fairly straightforward ways to lazy-load properties from persistent storage (or add that capability down the road if it becomes advantageous).
Accessing a field will not invoke other code.
I was unable to put a synchronized onto the field directly:
error: modifier synchronized not allowed here
public synchronized final Object field;
But when I locked it in code: synchronized (field) {
while(true) {
..
I was still able to access the synchronized field directly without triggering a deadlock - whereas a getter() could be synchronized and trigger a deadlock.In any case, the article already made a strong points for immutability so you don't need to mess around with deadlocking crap.
Although I suppose they could mean the concept and not the keyword. A field might not be thread safe and there's no way for an object to guarantee thread safe access of to a field.
You have to take a lock in order to deadlock in the public version. In the getter version, you can take a lock without realising it and then deadlock.
I mean, Lazy<T> is a great example of use of getters.
> You can add validation for all setters, and abstract it as an interface later if needed.
Sure, but why not just postpone the introduction of setters until you actually need them. 90% of time you don't, in which case we just saved a ton of boilerplate and ceremony. The 10% of time that you do, converting public variables to a setter method is about 2 IDE clicks these days.
The only argument I can think of is if you are exposing a public library API, in which case you need to worry about backwards API compatibility.
Trying to refactor fields that made it into a public API is a nightmare. If you're shipping code people use, you won't get to refactor their projects from your upstream library.
Also, no one is suggesting everything needs a setter. Where is this coming from?
this later literally never comes. if you didn't have an ontology when you wrote the code, it never magically unexpectedly appears.