Why Use Getters and Setters

suggest change

Consider a basic class containing an object with getters and setters in Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

We can’t access the count variable because it’s private. But we can access the getCount() and the setCount(int) methods because they are public. To some, this might raise the question; why introduce the middleman? Why not just simply make they count public?

public class CountHolder {
  public int count = 0;
}

For all intents and purposes, these two are exactly the same, functionality-wise. The difference between them is the extensibility. Consider what each class says:

These might sound similar, but the first is actually much more guarded in its nature; it only lets you interact with its internal nature as it dictates. This leaves the ball in its court; it gets to choose how the internal interactions occur. The second has exposed its internal implementation externally, and is now not only prone to external users, but, in the case of an API, committed to maintaining that implementation (or otherwise releasing a non-backward-compatible API).

Lets consider if we want to synchronize access to modifying and accessing the count. In the first, this is simple:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

but in the second example, this is now nearly impossible without going through and modifying each place where the count variable is referenced. Worse still, if this is an item that you’re providing in a library to be consumed by others, you do not have a way of performing that modification, and are forced to make the hard choice mentioned above.

So it begs the question; are public variables ever a good thing (or, at least, not evil)?

I’m unsure. On one hand, you can see examples of public variables that have stood the test of time (IE: the out variable referenced in System.out). On the other, providing a public variable gives no benefit outside of extremely minimal overhead and potential reduction in wordiness. My guideline here would be that, if you’re planning on making a variable public, you should judge it against these criteria with extreme prejudice:

  1. The variable should have no conceivable reason to ever change in its implementation. This is something that’s extremely easy to screw up (and, even if you do get it right, requirements can change), which is why getters/setters are the common approach. If you’re going to have a public variable, this really needs to be thought through, especially if released in a library/framework/API.
  2. The variable needs to be referenced frequently enough that the minimal gains from reducing verbosity warrants it. I don’t even think the overhead for using a method versus directly referencing should be considered here. It’s far too negligible for what I’d conservatively estimate to be 99.9% of applications.

There’s probably more than I haven’t considered off the top of my head. If you’re ever in doubt, always use getters/setters.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Getters and Setter:
* Why Use Getters and Setters

Table Of Contents
8 Arrays
10 Maps
11 Strings
25 JAXB
29 Enums
32 Audio
41 Scanner
63 Logging
75 Lists
78 Sets
83 Getters and Setter
89 JAX-WS
96 XJC
98 Process
106 Modules
114 Applets
122 JNDI
139 JavaBean
141 Literals
144 Packages
150 JMX
153 JShell
159 Sockets
167 Enum Map
175 Hashtable
177 SortedMap