Defining Classes and Instance Methods
A public variable gives direct access, but a getter and setter pair gives the class a place to run code when the value is read or written.
Why Direct Access Looks Good Enough
Suppose one class needs to read a value from another class and also change it. The quickest path seems to be declaring the variable public. Then any class can see it and assign to it directly, and there appears to be no need for extra methods. This is a common first reaction to getter and setter methods: they seem unnecessary. This section examines that belief, shows where it breaks down, and explains what getter and setter methods offer in return.
A useful way to think about the question is this. It is very common to provide both a getter and a setter for a private member variable, and that pairing lets other classes both read and change the value. So the real question is not whether other classes can see and change the value. The real question is what else the class can do when they do.
What a Public Variable Cannot Do
A public variable is accessed directly. There is no method in between, so there is no place for the class to run any code at the moment the value is read or written. Whatever the class wants to know about its own data, it cannot learn from a direct access, because nothing in the class is involved in that access at all.
A getter and setter pair changes this picture. Each read goes through the getter method, and each write goes through the setter method. Because those methods are code that the class controls, the class gets a point where it can respond to every access. The source states the key idea directly: getters and setters are not restricted to reading and writing a value. They can take any action at all.
Tracing a Getter That Counts Reads
The source's example is a getter that keeps track of how many times the variable has been accessed. The following class is an original illustration built on that idea. It stores a temperature in a private variable and keeps a private counter of how many times the getter has been called. Read it carefully, because the goal is to follow the state of the counter as calls happen.
- temperature and
readCountare private, so only code inside Thermometer can touch them directly getTemperatureincrementsreadCountbefore it returns the stored temperaturesetTemperatureis the public write path for temperature
Before you look at the sequence below, predict what happens to the counter. The class starts with readCount at 0. Another class calls getTemperature() twice. What is readCount afterward, and what is the caller's code that makes the calls? Think about it before you check the answer.
What do you think happens?
After two calls to getTemperature() on a new Thermometer, what is readCount?
Reveal answer
readCount is 2.
Each call to getTemperature() runs readCount++ once before returning, so two calls increment the counter twice. The calling code never mentions readCount; the increment happens inside the method.
The diagram shows the order of the steps. The caller enters the getter, the getter updates the counter, the getter reads the private temperature, and the value goes back to the caller. The caller never touches readCount. If temperature had been public, the caller could have read it directly, and the Thermometer class would have no record of that access. The getter is the only place where the class can respond to the access.
readCount = 0 // new Thermometer, no calls yetreadCount is 0
readCount = 1 // after one call to getTemperature()readCount is 1 after the first getTemperature() call
Tracking three reads of the same temperature
A Thermometer is created with temperature set to 21.5 and readCount at 0. Calling code then calls getTemperature() three times in a row. What does each call return, and what is readCount after the third call?
- 1Set up the starting state
setTemperature(21.5)stores 21.5 in temperature.readCountis still 0 because no getter has run. - 2First call
readCount++ makesreadCount1. The method returns temperature, which is 21.5. - 3Second call
readCount++ makesreadCount2. The method returns 21.5 again, since nothing changed temperature. - 4Third call
readCount++ makesreadCount3. The method returns 21.5 once more.
Each call returns 21.5, and readCount is 3 after the third call. The returned value and the counter are independent: the getter returns the stored value and also records the access.
Keeping the Public Interface Stable
The second major benefit concerns change over time. A class's public interface is the set of members that other classes are allowed to use. The source states that the private member variable is not part of that interface. Only the public getter and setter methods are. Because of this, the implementation behind those methods can change without changing the interface that other code depends on.
Calling code reaches the private variable only through the two public methods, and those methods form the boundary. If the internal storage or the logic inside a method is changed later, the calling code keeps working, because it never depended on the private variable itself. What stays fixed for callers is the property name and the getter and setter signatures. What may change is how the value is stored and computed inside the class.
The source also describes the cost of skipping this step. If a class was first written with a public variable and later needs a getter and setter, every class that uses that variable must be found and updated. Using the methods from the start avoids that work. The source makes this point even when no extra chores for the methods are yet visible, because the design may change later.
| Feature | Public variable | Getter and setter pair |
|---|---|---|
| How callers access the value | Read and written directly | Read through getX() and written through setX() |
| Place to run code on access | None, because no method is involved | Inside the getter or setter, which can run any action |
| Record of accesses | The class has no record of direct reads | The getter can count accesses, as in the Thermometer example |
| Effect of changing internal storage | Every class that used the variable may need updating | Callers keep working as long as the method signatures stay the same |
| Member variable in the public interface | The variable itself is public | The variable stays private and is not part of the public interface |
Public variable versus getter and setter pair
Methods That Define a Property Without a Variable
So far the methods have been tied to a variable. The source points out that this link is not required. You can define getter and setter methods even when there is no variable at all. A getter or setter defines a property of the class, and that property may or may not correspond to a member variable. The property is defined by the method signatures, not by storage.
The naming convention determines the property name. For a property named value, the setter is written as setValue, with the word set followed by the property name with its first letter capitalized. A getter for the same property is getValue. The source's own example uses a public void instance method with the signature setValue(double), which gives the class a property named value of type double whether or not a member variable named value exists. The name of the property comes from the method, not from the variable.
- There is no member variable at all in this class
getGreetingdefines a property named greeting from its name alone- A caller reads the property by calling
getGreeting(), and the value comes from the method body each time
In this class, the value is produced fresh each time the property is read. Nothing is stored between reads. Compare this with the Thermometer, where the getter returns a stored field. The two classes present the same kind of property to callers, but the source of the value differs: one reads storage, and the other computes or returns a value from the method body.
Mistakes Beginners Make
Common mistake Making the variable public because it seems faster to write
Why it failsA public variable removes the only place where the class can run code when the value is read or written, so later changes may require updating every caller.
Do this insteadKeep the variable private and expose it through a getter and setter from the start.
Common mistake Assuming a getter must always return a stored variable
Why it failsThe getter is ordinary method code, and the source says a property can exist even when no member variable exists.
Do this insteadLet the getter return a stored field, perform an extra action such as counting, or return a value computed in its body.
Common mistake Giving the method a name that ignores the convention
Why it failsThe source recommends following the naming convention carefully because some advanced aspects of Java rely on it.
Do this insteadUse set followed by the property name with a capital first letter, and get followed by the same name for the getter.
Common mistake Expecting callers to know about the counter
Why it failsCallers in the Thermometer example never mention
readCount. The counting is a private detail inside the method.Do this insteadKeep the counter private, and let the getter handle the bookkeeping as part of its job.
Practice: Add a Read Counter
Start from the Thermometer class. Add a private int field named readCount if it is not already there, and make getTemperature increment it before returning the temperature. Then describe, in one or two sentences, what changes for calling code. Does the calling code need to be modified, and why or why not?
Hints
- The increment belongs inside
getTemperature, before the return statement. - Think about whether the caller can see
readCount, and whether it has to. - Compare the caller's code before and after the change.
Summary of Getters, Setters, and Properties
- 1A public variable gives direct access but no place for the class to run code when the value is read or written.
- 2A getter and setter pair routes every read and write through methods that the class controls, so the class can take any action, such as counting accesses.
- 3The private variable is not part of the public interface, so the implementation can change without affecting classes that use the class.
- 4A getter or setter defines a property even when no member variable exists, and the property name comes from the method name following the Java naming convention.
At a glance
- A public variable gives direct access, but a getter and setter pair gives the class a place to run code when the value is read or written.
- A getter can perform extra actions, such as counting how many times a variable has been accessed.
- Keeping the variable private and exposing getters and setters lets the implementation change without breaking callers.
- A property is defined by its getter and setter method signatures, so a property can exist even without a matching member variable.