What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More

Getters and Setters in Java (with Examples)

  • Dec 01, 2023
  • 15 Minutes Read
Getters and Setters in Java (with Examples)

Java getters and setters play a pivotal role in object-oriented programming by enabling controlled access to class fields or attributes. At its core, these methods ensure data encapsulation, a fundamental principle in OOP. Encapsulation involves bundling the data (attributes) and methods (getters/setters) that operate on the data within a single unit, i.e., a class. This article aims to explain the best practices for implementing getters and setters, as well as their significance in encapsulation and complexity.

What are Getters and Setters?

Getters and setters, also known as accessor and mutator methods, respectively, are integral components in Java for managing class attributes or fields. These methods are responsible for accessing and modifying the private fields of a class, allowing controlled interaction with its data.

The getter method retrieves the value of a private field and returns it to the caller. It follows a naming convention prefixed with "get" followed by the field name. For instance:

public class Person {
    private String name;

    // Getter method
    public String getName() {
        return name;
    }
}

 

In this example, getName() retrieves the value of the private name field.

On the other hand, the better method updates or modifies the value of a private field. It follows a naming convention prefixed with "set" followed by the field name. For example:

public class Person {
    private String name;

    // Setter method
    public void setName(String newName) {
        this.name = newName;
    }
}

 

Here, setName() updates the value of the private name field.

These methods facilitate controlled access to class fields, enforcing encapsulation by abstracting the internal representation of data. They allow implementing validation, error checking, and logic control while accessing or modifying the fields.

The distinction between getters and setters lies in their functionality: getters retrieve data, while setters modify or update data. Together, they promote data integrity and help in maintaining a clean interface for interacting with class attributes.

Structure of Getters and Setters

Getters and setters are ordinary Java methods used to access and modify the private fields of a class. They follow a specific naming convention that aids in identifying their purpose and association with corresponding class fields.

The basic structure of a getter and setter:

public class MyClass {

    private DataType fieldName;

    // Getter method
    public DataType getFieldName() {
        return fieldName;
    }

    // Setter method
    public void setFieldName(DataType newValue) {
        this.fieldName = newValue;
    }
}

 

Here, fieldName represents a private field in the class MyClass. The getter method getFieldName() returns the value of field Name, while the setter method setFieldName() allows modification of the field Name value.

Access Modifiers: Public, Private, Protected

Getters and setters can have different access modifiers that control their visibility and accessibility:

  • Public: When declared as public, these methods are accessible from outside the class and enable external code to read or modify the class's private fields.
  • Private: Typically, the fields they manipulate are private, allowing controlled access from within the class itself.
  • Protected: These methods can be accessed within the class and its subclasses, fostering inheritance while maintaining encapsulation.

Example:

public class Student {

    private String name;

    // Public getter method
    public String getName() {
        return name;
    }

    // Private setter method
    private void setName(String newName) {
        this.name = newName;
    }
}

 

In this example, the getName() method is public, allowing external classes to access the name field, while setName() is private, restricting direct modification of name from outside the Student class.

Using the 'this' Keyword

The 'this' keyword refer to the current instance of the class and is commonly used within getters and setters to differentiate between class fields and method parameters when the share the same name.

public class Person {

    private String name;

    // Setter method using 'this' keyword
    public void setName(String name) {
        this.name = name;
    }
}

 

Here, this.name distinguishes the name field of the class from the neme parameter passed to the method.

What is Encapsulation and its Significance?

Encapsulation is a fundamental principle in object-oriented programming that bundles data (attributes or fields) and the methods (getters/setters) that operate on that data within a single unit, i.e., a class. It aims to restrict direct access to certain components of an object and instead promotes controlled access via methods.

How do Getters and Setters Enforce Encapsulation?

Getters and setters play a pivotal role in encapsulation by providing a controlled interface to interact with class fields. By making fields private and providing public methods to access or modify these fields, they shield the internal state of an object from direct manipulation by external classes.

Example:

public class BankAccount {
    private double balance;

    // Getter method with public access
    public double getBalance() {
        return balance;
    }

    // Setter method with validation
    public void setBalance(double newBalance) {
        if (newBalance >= 0) {
            this.balance = newBalance;
        } else {
            System.out.println("Invalid balance");
        }
    }
}

 

In this example, the balance field is kept private, and external classes can only access it through the getBalance() method. The setBalance() method allows modification of balance, but it includes validation logic to ensure that only valid values are accepted.

Advantages of Controlling Data Access

Controlled data access offers several advantages, including:

  • Security: Prevents unauthorized access and manipulation of sensitive data.
  • Validation: Enables validation and error checking before setting or retrieving data, ensuring data integrity.
  • Flexibility: Facilitates modifications to the internal implementation without affecting external code using the class.

By utilizing getters and setters to enforce encapsulation, Java developers can design robust and secure classes while maintaining flexibility and control over their data.

Overview of Java Bean Specification

Java Beans are reusable software components adhering to specific conventions, facilitating their integration into various Java applications. These conventions define rules for creating Java classes to ensure consistency and interoperability.

How Getters/Setters Adhere to Java Bean Standards?

Java Beans follow a set of conventions, including the use of getters and setters to access and modify  properties (class fields). By adhering to these conventions, Java classes become compatible with various frameworks, tools, and development environments that rely on Java Beans.

Example:

public class User {

    private String username;

    // Getter method following Java Bean convention
    public String getUsername() {
        return username;
    }

    // Setter method following Java Bean convention
    public void setUsername(String username) {
        this.username = username;
    }
}

 

The adherence to Java Bean standards, specifically the use of appropriate getters and setters, allows these classes to be seamlessly integrated into frameworks like JavaFX, Spring, or other Java-based tools that leverage Java Bean specifications.

Working with Frameworks and Libraries Based on Java Beans

Frameworks and libraries built around Java Beans benefit from consistent class structures, allowing them to introspect and manipulate classes dynamically. This dynamic manipulation is often utilized in various contexts, including graphical user interface development, serialization, and data binding.

Java developers leverage these standards to build robust and interoperable software components, enabling easy integration and compatibility across a wide range of Java-based systems.

Advanced Usage and Patterns of Getters and Setters

Let’s see some advanced usage of Getters and Setters.

1. Fluent Interfaces and Chaining with Setters

Fluent interfaces are a design pattern that enables method chaining, allowing consecutive method calls on an object without re-specifying the object each time. This pattern can be applied to setters, enhancing readability and conciseness.

public class Person {
    private String firstName;
    private String lastName;

    public Person setFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public Person setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }
}

// Using fluent interfaces
Person person = new Person()
    .setFirstName("John")
    .setLastName("Doe");

 

2. Using Lombok or Other Tools for Auto-Generetion Getters/Setters

Lombok is a Java library that reduces boilerplate code by automatically generating getters, setters, constructors, and more. It utilizes annotations to generate these methods at compile time, streamlining class definitions.

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Book {

    private String title;
    private String author;
    // Automatically generates getters and setters
}

 

By annotating fields with @Getter and @Setter, Lombok generates corresponding getter and setter methods during compilation, reducing code verbosity.

3. Applying Getters/Setters in Inheritance and Polymorphism

Inheritance allows classes to inherit attributes and methods from their parent class. Getters and setters in parent classes can be inherited by subclasses, providing a consistent interface for accessing and modifying inherited properties.

public class Vehicle {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

public class Car extends Vehicle {
    // Inherits getType() and setType() from Vehicle
}

 

Subclasses inherit the getter and setter methods from the parent class, allowing them to access and modify inherited properties seamlessly.

These advanced usage patterns demonstrate how getters and setters can be leveraged in various ways, enabling cleaner code, enhanced readability, and flexible design patterns in Java.

Conclusion

Java getters and setters, fundamental to encapsulation, are essential components in Java classes, enabling controlled access to class fields while maintaining data integrity and security. Throughout this article, we've explored various aspects of getters and setters, including their functionality, usage patterns, best practices, and real-world applications. 

FavTutor - 24x7 Live Coding Help from Expert Tutors!

About The Author
Nihal Mahansaria
As a computer science student with a passion for technology and a drive to learn, I have developed a diverse set of skills in web development, machine learning, and technical content writing. With experience in multiple front-end and back-end frameworks, including Flask and Python, I am able to create scalable and efficient web applications.