Lesson 10 - Getters and setters in Java

Java OOP Getters and setters in Java

In the previous lesson, Static class members in Java, we learned about static class members in Java. In today's tutorial, we're going to look at getter and setter methods.

Getters and setters

We often want to have control over how an object field changes from outside of the class. We could set the field as read-only or react to its changes somehow. Let's create a new project (name it GetSet) and add the following Student class which will represent a student in a database.

public class Student {
        public String name;
        public boolean male;
        public int age;
        public boolean fullAged;

        public Student(String name, boolean male, int age) {
                this.name = name;
                this.male = male;
                this.age = age;
                fullAged = true;
                if (age < 18) {
                        fullAged = false;
                }
        }

        @Override
        public String toString() {
                String iAmFullAged = "I'm";
                if (!fullAged) {
                        iAmFullAged = "I'm not";
                }
                String gender = "male";
                if (!male) {
                        gender = "female";
                }
                return String.format("I'm %s, %s. I'm %d years old and %s of age.", name, gender, age, iAmFullAged);
        }

}

The class is very simple, the student has a name, gender, and age. The fullAged field is set according to the age and provides a more comfortable determination whether the student is of age from different places in the system. We'll use a boolean value to store gender, true indicates that he's male. The constructor will determine whether the student is of age or not. The toString() method has been altered to suit our needs. In a real world situation, it would probably just return the student's name. Let's create a student using the constructor:

Student s = new Student("Peter Brown", true, 20);
System.out.println(s);

The output:

Console application
I'm Peter Brown, male. I'm 20 years old and I'm of age.

Everything looks nice, but the fields are able to be re-written. Here, the object would no longer function properly (i.e. it has an inconsistent internal state):

Student s = new Student("Peter Brown", true, 20);
s.age = 15;
s.male = false;
System.out.println(s);

The output:

Console application
I'm Peter Brown, female. I'm 15 years old and I'm of age.

Certainly, we would want fullAged to be updated when the age is changed. Aside from that, there is no need to allow e.g. a gender to be changed. However, we'll keep the fields accessible for reading. In earlier parts of our course, we've used get methods to read private fields. We would name them something like getAge() and so on. In Java, we declare all the fields which should be accessible from the outside as private and we implement similar methods to make them accessible. We name them as getFieldName() for reading and setFieldName() for writing. For boolean fields, we usually name getters as isFieldName(). The class would now look something like this:

public class Student {
        private String name;
        private boolean male;
        private int age;
        private boolean fullAged;

        public Student(String name, boolean male, int age) {
                this.name = name;
                this.male = male;
                setAge(age);
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public boolean isMale() {
                return male;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
                // updating whether student is of age
                fullAged = true;
                if (age < 18) {
                        fullAged = false;
                }
        }

        public boolean isFullAged() {
                return fullAged;
        }

        @Override
        public String toString() {
                String iAmFullAged = "I'm";
                if (!fullAged) {
                        iAmFullAged = "I'm not";
                }
                String gender = "male";
                if (!male) {
                        gender = "female";
                }
                return String.format("I'm %s, %s. I'm %d years old and %s of age.", name, gender, age, iAmFullAged);
        }

}

Methods used for returning values are very simple. When a user changes his/her age, our program recalculates the fullAged field. We made sure we can't set variables in any other way than what we want. We now control all the field changes and can work with them as needed. Our design must prevent all alterations of the internal state that would cause an object to malfunction. Notice the change in the constructor where we set the age using the setAge() method.

Methods for returning values are called getters and methods for setting values are called setters. We could potentially add an editStudent() method to edit other fields sort of like we did to the constructor. Essentially, a student's name, age, and other fields would be updated using this method. We could also validate values being set there since we would be able to handle all attempts to change certain values in one place.

The question now is, what are the benefits of the name field being private when we can both write it and read it? We now got 2 methods for accessing it which only occupies place in the code. And isn't it also slower?

We really wrote that right, or at least as Java programmers usually do that. Java performs many optimizations before compiling so if the methods are as simple they only return a value, the method is compiled as a direct access to the memory. SO they are as fast as we used plain attributes (considering there is no other logic in the getter).

IDE (NetBeans) can generate getters and setters automatically for us, there is no need to write them over and over again. The only this we need to do is to click on the variable with the right mouse button and choose Redactor -> Encapsulate fields.

Generating getters and setters in NetBeans automatically

In the next dialog, we specify for which fields we want to generate getters and setters for. We won't generate setters for fullyAged and male fields, making them read-only. There is no sense in changing the gender at all (if really needed, there would be some special method to avoid doing that accidentally). We confirm the dialog.

Encapsulating fields in NetBeans automatically

Compiler optimizations solved the performance issue which would be caused by calling the methods otherwise. We also bypassed manual writing methods manually by generating them automatically. The question still is, what are the benefits?

The main reason is some kind of standardization. We don't have to think about whether the property we want to access has a getter or it's a public field, we just always call the method starting with get* on the instance, resp. set* if we want to change it.

Another benefit is that we can decide later that we want to make some field as read-only, we just remove the setter. We don't have to create a getter and change the field access modifier, which would change the class interface and break existing code using it.

From now on, we'll generate getters and setters for all fields which should be accessible from the outside. There will be almost no public fields in our classes anymore.

Let's try the code that broke the object's inner state once more:

Student s = new Student("Peter Brown", true, 20);
s.setAge(15);
// s.setMale(false); // This line has to be commented out since it's no longer possible to change the gender
System.out.println(s);

And the output is correct now:

Console application
I'm Peter Brown, male. I'm 15 years old and I'm not of age.

In the next lesson, Lists in Java, we'll learn about lists in Java.


 

 

Article has been written for you by David Capka
Avatar
Do you like this article?
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn College The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.
Thumbnail
Previous article
Static class members in Java
Thumbnail
All articles in this section
Object-oriented programming in Java
Thumbnail
Next article
Lists in Java
Activities (8)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!