Getter/Setter — the most hated practice in Java.

Hussachai Puripunpinyo
Zappos Engineering
Published in
5 min readJan 29, 2016

You should use getter/setter.
You should use getter/setter.
You should use getter/setter.
If you don’t, you are not a good programmer. Really?

But, creating getter and setter is the excellent way to pollute your code. Most of the time, you don’t do anything with the variable in getter and setter methods. Why bother having them after all? If your company pays you by lines of code, I bet you will never complain about having them. (You’d rather quit that company instead. I mean after you have generated a million lines of useless code ;P)

Actually, getter and setter methods are not useful at all if you’re really sure that you will not use your class differently from your initial intention. I emphasized the word `really` because code almost always evolves beyond our initial intent. That’s why it has become good practice to have getter and setter methods for a variable and never allow accessing a variable directly! Look at the following code:

class YourClass {
public int myVar;
}
class SomeoneElseClass {
public void doSomethingWithYourClass(YourClass yc){
yc.myVar = getValueFromBlackhole();
transmitToWhitehole(yc);
}
}

One day, you think it’s better to add the validation logic for the variable myVar because other people keep sending incorrect values to your system. Without a setter, you can’t fix it by yourself. You have to ask other people to change their code if you want to change the visibility of the variable myVar from public to private and expose the setter method that alters the variable myVar. If the only person who uses your code is the person that sits next to you, it would not be difficult to politely ask them do so. The worse solution is asking them to add the validation logic before setting myVar variable in their code. Imagine that there are a lot of people who are using your code and you don’t know them. Furthermore, if they are a customer, they’re not going to fix your problem. That’s why people keep saying you should use getter and setter methods.

This good practice can become irrelevant when you use a language that can hook getter and setter methods to the existing interface. So, you don’t have to pollute your code by writing getter and setter methods explicitly right from the get-go.

I will show you why you don’t have to declare getter and setter methods in some languages.

Python
In Python, you can declare the public variable that allows other classes access it directly. It sounds really bad if you’re a Java programmer but for Python folks, this is normal because they can change their mind later by adding the property function (method) without affecting the interface.

//Your class
class YourClass(object):
my_var = 0
class SomeoneElseClass(object):
def do_something(self, yc):
yc.my_var = get_value_from_blackhole()
transmit_to_whitehole(yc)

When you want to add the setter method for the variable my_var later, you can do so by using annotations as the following:

class YourClass(object):
my_var = 0
@property
def my_var(self):
return self._my_var

@my_var.setter
def my_var(self, value):
print(“Easy peasy”)
self._my_var = value

The alternative approach is to use the property function instead of annotations.

class YourClass(object):
def get_my_var(self):
return self._my_var
def set_my_var(self, value):
print(“Easy peasy”)
self._my_var = value
my_var = property(get_my_var, set_my_var)

C#.NET

C# has special syntax for the property feature unlike Python that uses either annotations or functions. You might be mistaken that the following code is Java code. Yes, it does compile in Java. So, I adjusted the code format a bit to make it more like .NET :).

class YourClass
{
public int MyVar;
}
class SomeoneElseClass
{
public void DoSomethingWithYourClass(YourClass yc)
{
yc.MyVar = GetValueFromBlackhole();
TransmitToWhitehole(yc);
}
}

One day you want to add a setter method, you can do so by declaring a property using the same name as public variable and change the backing variable name to something else. Note that if you want to add the mutator (setter) to the property, you also have to add the accessor (getter). Otherwise, it won’t compile. In contrast, you can add just the accessor without having the mutator.

class YourClass
{
//rename MyVar to myVar and use it as backing variable
private int myVar;
//add property MyVar to replace MyVar variable
public int MyVar
{
get { return myVar; }
set
{
System.Console.WriteLine(“Easy peasy”);
myVar = value;
}
}
}

Scala

Scala doesn’t have special keywords, annotations or functions to implement the property feature like in Python, .NET and some other languages. Scala uses naming convention to do that and the compiler knows how to handle it specially.

class YourClass() {  
var myVar = ""
}
class SomeoneElseClass() {
def doSomething(yc: YourClass) = {
yc.myVar = getValueFromBlackhole()
transmitToWhitehole(yc)
}
}

If you want to add the setter method for the variable myVar, you have to rename the variable myVar to _myVar (can be any name that will not collide with myVar) and change its visibility to private. You also have to declare the function named myVar for the accessor and myVar_= for the mutator. Note that you have to declare both accessor and mutator methods in order to make the mutator works. (same rule as Python and C#.NET)

class YourClass() { 
//rename myVar variable to _myVar
private var _myVar = 0
//getter
def myVar = _myVar
//setter
def myVar_= (value: Int): Unit = _myVar = value
}

But, really? Who use this feature in Scala anyway :P. Some Scala folks don’t even know that this feature exists. You can program Scala the same way you do with Java, but that’s discouraging. Scala folks seem to enjoy having no mutable state in their program and make their code functional as much as possible. Mutable states are for exceptional cases only such as low level I/O.

What about Java?
Sorry, Java doesn’t have property feature out of the box, and it seems like they don’t have a plan to add it in the near future. At least, not in Java 9 or 10. Nevertheless, you can use a framework that can generate getter and setter methods for you. If you’re interested, take a look at project lombok. It is basically a code generation framework that generates the getter and setter methods for you behind the scenes. It also can generate other methods such as toString(), equals(), and hashCode(). It’s very nice to use this tool when you have a lot of data classes (no business logic just a plain POJO holding attributes).

When you have lombok working in your project, you just have to annotate your data class with @Data annotation like the following.

public class @Data YourClass {
private int myVar;
}

Lombok will generate code and compile. You won’t see the code that it generates but it will be similar to the following.

public class YourClass {
private int myVar;

public int getMyVar(){
return myVar;
}

public void setMyVar(String myVar){
this.myVar = myVar;
}
@Override public String toString(){
return "YourClass(" + this.getMyVar() + ")";
}
protected boolean canEqual(Object other) {
return other instanceof YourClass;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if(! (o instanceof YourClass)) return false;
YourClass other = (YourClass)o;
if(!other.canEquals((Object)this)) return false;
if(this.getMyVar() != other.getMyVar()) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result * PRIME) + this.geMyVar();
return result;
}
}

That’s nice, isn’t it? I know that other languages provide this feature out of the box. But, if you have to use Java, lombok is the way to go.

--

--

Hussachai Puripunpinyo
Zappos Engineering

Daytime stay-at-home dad, nighttime entrepreneur. A man with dreams far greater than himself. My work: https://tailrec.io