Introduction
In Object-Oriented Programming (OOP), one of the core principles is encapsulation—bundling data and behavior together while restricting direct access to internal object states. In Java, getters and setters are essential tools for achieving encapsulation.
This tutorial explores what getters and setters are, why they matter, when to use them, and how to implement them properly. We’ll also look at common pitfalls, Java-specific syntax, use cases in enterprise applications, and best practices for clean and secure code.
What Are Getters and Setters in Java?
Definition
- A getter is a public method that returns the value of a private field.
- A setter is a public method that sets or updates the value of a private field.
They help enforce access control and maintain the integrity of an object’s internal state.
Syntax
class Person {
private String name;
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String name) {
this.name = name;
}
}
Why Use Getters and Setters?
- Encapsulation: Prevents external code from directly modifying fields
- Validation: Add logic to prevent invalid data entry (e.g., negative age)
- Debugging and Logging: Track access and changes to sensitive fields
- Flexibility: Future-proof your class structure
- Framework Compatibility: Many libraries (like Hibernate and Spring) rely on getters/setters
Real-World Use Case
Imagine a BankAccount class. You wouldn’t want the balance
to be changed directly.
class BankAccount {
private double balance;
public double getBalance() {
return balance;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
}
Here, the setter is replaced with a controlled deposit()
method to prevent misuse.
UML-Style Representation
Class: Person
|-- -name: String
|-- +getName(): String
|-- +setName(String): void
When Not to Use Setters
- When the field should be immutable after initialization
- When the setter offers no additional value beyond
this.field = value
- When using record classes in Java 16+, which are inherently immutable
Common Pitfalls and Fixes
Pitfall | Solution |
---|---|
Using public fields | Always keep fields private |
No input validation | Validate data inside setters |
Blindly exposing all fields | Only expose what's necessary |
Setting null/invalid state | Add null checks or exceptions |
Example: Safe Setter
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age must be non-negative");
}
this.age = age;
}
Comparison with Related OOP Concepts
Concept | Description |
---|---|
Encapsulation | Hides internal state; getters/setters help achieve this |
Immutability | No setters; field is set once (e.g., via constructor) |
Records (Java 16+) | Automatically generate getters; no setters |
Refactoring Example
Before (Public Field)
class Product {
public double price;
}
After (Encapsulated with Validation)
class Product {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
if (price > 0) this.price = price;
}
}
Java 17/21 Considerations
Records (Java 16+)
record Person(String name, int age) {}
- Automatically provides immutable fields and getters.
- Ideal for DTOs and value-based objects.
Sealed Classes
Restrict subclassing, often working with private fields and controlled access.
sealed class Shape permits Circle, Rectangle {}
Best Practices
- Keep fields private and expose only necessary ones
- Validate input inside setters
- Avoid setters for fields that shouldn't change
- Use
final
and constructors for immutability where possible - Consider using IDE tools or Lombok to reduce boilerplate
Real-World Analogy
Think of a vending machine. You can press a button (getter) to see the product and insert a coin (setter with validation). You can’t just reach in and change the items inside—it’s controlled.
Conclusion
Getters and setters in Java are simple yet powerful tools that promote encapsulation, data safety, and maintainability. When used correctly, they help ensure your objects behave predictably and remain valid throughout their lifecycle. With Java's newer features like record
and sealed
classes, there's even more flexibility to choose the right design pattern.
Key Takeaways
- Getters return values; setters assign them with control.
- Always keep fields private and expose them via accessors.
- Validate data inside setters to avoid invalid state.
- Use immutability when appropriate—skip setters if not needed.
- Java 16+ provides
record
for clean, immutable data classes.
FAQ – Getters and Setters in Java
1. Can I use getters without setters?
Yes. For read-only properties, use only a getter.
2. Are getters and setters required for every field?
No. Only create them for fields that need controlled access.
3. Can I make a setter private?
Yes. Useful for read-only fields after object creation.
4. What’s the JavaBeans convention?
Getter: getField()
; Setter: setField(value)
5. Do records use getters and setters?
Records generate getters only. Fields are final.
6. Can getters/setters be overridden?
Yes, if they're non-final and in an inheritable class.
7. Are getters/setters slower than direct access?
Negligibly. Benefits in flexibility outweigh minor cost.
8. Is using Lombok @Getter
and @Setter
a good idea?
Yes, for reducing boilerplate. Use carefully in public APIs.
9. Can I use setters for validation?
Yes. It’s a common use case.
10. Do frameworks like Spring need getters/setters?
Yes. Many frameworks rely on them for data binding and serialization.