Dean J Dean J - 1 month ago 15
Java Question

Why use getters and setters?

What's the advantage of using getters and setters - that only get and set - instead of simply using public fields for those variables?

If getters and setters are ever doing more than just the simple get/set, I can figure this one out very quickly, but I'm not 100% clear on how:

public String foo;


is any worse than:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }


Whereas the former takes a lot less boilerplate code.



Compiling the list up here at the top of what seemed winners to me, from the viewpoint of a Java web dev:


  1. When you realize you need to do more than just set and get the value, you don't have to change every file in the codebase.

  2. You can perform validation here.

  3. You can change the value being set.

  4. You can hide the internal representation. getAddress() could actually be getting several fields for you.

  5. You've insulated your public interface from changes under the sheets.

  6. Some libraries expect this. Reflection, serialization, mock objects.

  7. Inheriting this class, you can override default functionality.

  8. You can have different access levels for getter and setter.

  9. Lazy loading.

  10. People can easily tell you didn't use Python.


Answer

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.

Here are the some of the reasons I am aware of:

  • Encapsulation of behavior associated with getting or setting the property - this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change - allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property - particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/setters - Mocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.