Implementing Setter Methods
A getter method provides read access to a variable by returning its current value to the caller.
A Book That Guards Its Title
Imagine a class that stores information about a book. The class keeps the book's title inside a member variable. Other parts of a program often need to know that title, but they should not have to reach into the class and grab the variable directly. Instead, the class can offer methods that control how the variable is read and how it is changed. This article covers the two most common of those methods: the getter, which hands a value out, and the setter, which accepts a new value and stores it.
Keep the book example in mind as you read. The goal is to see how a method can give other code a way to read a variable's value, how the method is named, how a setter takes a new value in, and where things commonly go wrong when you write one yourself.
What do you think happens?
A class has a title field that was set when the object was created. A caller asks the class for the title through a getter. What does the caller receive?
Reveal answer
The caller receives the value the title field holds at the moment the getter runs.
The getter does not return a copy of some saved default or a value from earlier. It reads the variable as it is right now and returns that value. Because a getter only reads, the value the caller receives is simply whatever the field contains at that instant.
Reading a Value Through a Getter
A getter method is a method whose purpose is to return the current value of a variable. Because it only passes a value out, programmers describe it as providing read access to that variable. The method reads the variable on behalf of the caller and returns what it finds there.
Think of a getter as a window for looking at a value. The caller receives the value the variable holds at the moment the method runs. When you read a getter, treat it as a question the caller asks and the class answers with the stored value. Calling a getter does not change the stored value. It only reads it.
- The field title is private, so code outside the class cannot read or change it directly.
getTitleis public, so any caller can ask for the title.- The return type String matches the type of the field it reads.
- The body only returns the stored value; it never assigns to title.
Tracing a getter call
A Book object was created with the title Dune. The caller runs the statement String result = book.getTitle(); What value ends up in result?
- 1Create the object
The constructor assigns Dune to the private field title.
- 2Call the getter
The caller invokes
getTitle(). Control moves into the method body. - 3Read the field
The method body reads the current value of title, which is Dune.
- 4Return the value
The value flows back out through the return and is assigned to result. The field itself is unchanged.
result holds Dune, and title still holds Dune afterward.
Naming Getters and Setters
Java programmers follow a naming convention for getters. The name is not chosen freely. It is derived from the variable it reads, so that anyone who knows the variable's name can guess the getter's name. The derivation has two mechanical steps that you can apply to any variable: capitalize the first letter of the variable's name, then place get in front of it.
The same convention governs setters. A setter's name begins with the word set, followed by the capitalized variable name. A variable called title therefore gets a setter called setTitle. The setter also has a parameter whose type matches the type of the variable it sets. For a String field, the parameter is a String.
Changing the prefix in one of these names is what the convention is designed to prevent. Following the two rules, the name prefix and the matching parameter type, makes the setter easy to find and easy to use correctly.
Tracing a Setter Call
Consider a class with a private String field named title and a setter that does nothing except copy the incoming value into the field. The setter is written like this:
- The name
setTitlefollows the set-plus-capitalized-variable rule. - The parameter title is a String, matching the type of the field.
- The assignment
this.title= title copies the parameter into the private field.
When calling code writes a new value through a setter, control leaves the caller and enters the setter. The value passed in is bound to the parameter. The setter then performs its body, and the body is what reaches the private variable. Control returns to the caller once the body finishes. The diagram below shows the participants involved and the order of their messages.
The reason setters exist is protection. A class often keeps its data in private variables so that code outside the class cannot change them directly. That protection is only useful if the class still offers a legitimate way to change the data. A setter provides that way. Because all changes pass through one method, the class has a single place to decide whether a change should be allowed.
Adding Validation with a Safe Default
Validation means checking a new value before it is assigned to the private variable. The check decides whether the value is legal. When the value is not legal, the setter does not store it as given. Instead, it stores a default value that the class considers acceptable. Validation can keep null and other invalid values out of private variables, so that the rest of the class can rely on the field holding something usable.
- The null check is the validation step: it tests whether the incoming value is invalid.
- The first branch stores the safe default (Untitled) instead of null.
- The second branch stores the value unchanged, since it passed the check.
- Only one branch runs per call, and the field always ends up holding a value.
public void setTitle(String title) {
this.title = title;
}Passing null stores null in title, so later code may receive an unusable field.
public void setTitle(String title) {
if (title == null) {
this.title = "(Untitled)";
} else {
this.title = title;
}
}Passing null stores (Untitled) in title, and any other value is stored unchanged.
Finding Where a Result Diverges
When a setter seems to store the wrong value, the fastest way to find the fault is to ask which line produced the stored value. Start from the variable and work backwards. Ask whether the setter was called at all, which value reached the parameter, which branch the check took, and what the assignment stored. A mismatch at any of these points tells you where to look.
Locating a divergence in a validated setter
The caller runs book.setTitle(null) and then prints book.getTitle(). The caller expected null to be printed, but the output is (Untitled). Where does the stored value diverge from the expected result?
- 1Check the call
setTitlewas called with null, so the value reached the parameter as the caller intended. - 2Check the branch
The condition title == null is true, so the first branch runs.
- 3Check the assignment
The first branch assigns (Untitled) to the field. This is the point where the stored value stops matching the caller's value.
- 4Compare with the getter
getTitlereads the field and returns (Untitled). The getter is not the fault; it faithfully returns what the setter stored.
The divergence is at the assignment inside the null branch. The behaviour is the validation working as designed, not a bug, but the caller must know that null is replaced by the default.
Mistakes with Getters and Setters
The following mistakes come up often when people first write getters and setters. Each one breaks either the naming convention or the single-gate idea that makes setters useful.
Common mistake Naming a setter without the set prefix or with a lowercase variable name
What it looks likevoid title(String title) or void settitle(String title)Why it failsThe convention is that the name begins with set followed by the capitalized variable name, so other programmers and tools cannot find the setter by the rule.
Do this insteadUse setTitle for the variable title.
Common mistake Using get for a boolean getter
What it looks likepublic boolean getDone()Why it failsFor boolean variables the is prefix replaces get, so the expected name is
isDone.Do this insteadWrite public boolean isDone().Common mistake Giving the setter a parameter type that does not match the field
What it looks likeprivate String title with void setTitle(int title)Why it failsThe parameter should have the same type as the variable it sets, so the value passed in cannot be stored without conversion.
Do this insteadDeclare the parameter as String to match the field.
Common mistake Assuming a getter changes the variable
What it looks likegetTitle() that also resets title to a default
Why it failsA getter only reads the variable; calling it does not change the stored value.
Do this insteadKeep the getter body to a read and a return.
Common mistake Writing to a private field from outside the setter
Why it failsIf a value can reach the field by a route other than the setter body, the validation placed in the setter is bypassed.
Do this insteadRoute every change through the setter so that the single check always runs.
Practice Tracing a Setter
A class has a private String field named title and the validated setter shown earlier. Trace the call book.setTitle(null) followed by book.setTitle(Emma) and then book.getTitle(). What does getTitle return, and at which step does the stored value differ from the first value passed in?
Hints
- Work through each call in order, and track what the field holds after each one.
- Ask which branch of the null check runs for each call.
getTitleonly reads the field, so its result equals the last value stored.
Write a getter named isActive for a private boolean field named active, and a setter named setActive that takes a boolean parameter and stores it directly. Then state which method the caller should use to read the flag.
Hints
- The boolean getter uses the is prefix in place of get.
- The setter parameter type must match the boolean field type.
Key Takeaways
- A getter provides read access to a variable by returning its current value, and calling it does not change the stored value.
- Getter names are derived from the variable name: get plus the capitalized name, or is plus the capitalized name for a boolean.
- A setter is the controlled way to change a private variable; its name begins with set, and its parameter type matches the field.
- Every change passes through the setter body, so validation placed there can replace an invalid value such as null with a safe default before it is stored.
- When a stored value looks wrong, trace backwards from the variable to the setter call, the parameter value, the branch taken, and the assignment.