Java > Object-Oriented Programming (OOP) > Encapsulation > Getters and Setters
Encapsulation with Getters and Setters in Java
This example demonstrates encapsulation in Java using getters and setters. Encapsulation is one of the fundamental principles of object-oriented programming (OOP), where you restrict direct access to an object's internal data and provide controlled access through methods. This promotes data hiding and helps maintain the integrity of the object's state. Getters (accessor methods) are used to retrieve the values of private instance variables, while setters (mutator methods) are used to modify them. This approach enables you to add validation logic or other controls within the setter methods, ensuring that the object's data remains consistent and valid.
Core Code Snippet: A Simple `Person` Class
This code defines a `Person` class with private `name` and `age` instance variables. Getters (`getName`, `getAge`) provide read-only access to these variables. Setters (`setName`, `setAge`) allow modification, but with validation to ensure data integrity. The `main` method demonstrates how to create a `Person` object, access its properties using the getters, and modify them using the setters. The setter for `age` includes a validation check to prevent setting an invalid age.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter for name
public String getName() {
return name;
}
// Setter for name
public void setName(String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
} else {
System.out.println("Invalid name provided.");
}
}
// Getter for age
public int getAge() {
return age;
}
// Setter for age with validation
public void setAge(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
} else {
System.out.println("Invalid age provided.");
}
}
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println("Name: " + person.getName()); // Output: Name: Alice
System.out.println("Age: " + person.getAge()); // Output: Age: 30
person.setAge(35);
System.out.println("New Age: " + person.getAge()); // Output: New Age: 35
person.setAge(-5); // Output: Invalid age provided.
System.out.println("Age: " + person.getAge()); // Output: Age: 35 (value remains unchanged)
}
}
Concepts Behind Encapsulation and Getters/Setters
Encapsulation is the bundling of data (attributes) and methods that operate on that data into a single unit (class). It hides the internal state of an object from the outside and requires all interaction to be performed through the object's methods. Getters and setters are the primary means of accessing and modifying the encapsulated data. They allow you to control how the data is accessed and modified, providing a mechanism for validation, logging, or other operations.
Real-Life Use Case
Consider a `BankAccount` class. The account balance should not be directly accessible from outside the class. Instead, a `getBalance()` (getter) method would provide access to the balance, and `deposit()` and `withdraw()` methods (acting as controlled setters) would handle modifications. The `deposit()` and `withdraw()` methods could include logic to prevent negative balances or flag suspicious activity.
Best Practices
Interview Tip
When discussing encapsulation in an interview, emphasize data hiding, data integrity, and controlled access. Be prepared to explain how getters and setters contribute to these goals and provide examples of validation logic that can be implemented within setters.
When to Use Getters and Setters
Use getters and setters when you need to control access to an object's internal state. This allows you to validate input, perform side effects (like logging), or change the way data is stored internally without affecting the external interface.
Memory Footprint
Getters and setters themselves have a negligible impact on memory footprint. The primary memory usage comes from the instance variables of the class. However, excessive use of getters and setters could potentially impact performance due to the overhead of method calls, though this is rarely a significant concern in modern Java applications.
Alternatives
Pros of Encapsulation and Getters/Setters
Cons of Encapsulation and Getters/Setters
FAQ
-
Why use getters and setters instead of directly accessing instance variables?
Getters and setters provide control over how instance variables are accessed and modified. This allows you to add validation, perform side effects, or change the internal implementation without affecting the external interface of the class. Direct access bypasses these controls, potentially leading to data corruption or inconsistencies. -
Can I have a setter without a getter or vice-versa?
Yes, you can have a setter without a getter or a getter without a setter. A getter without a setter implies read-only access, while a setter without a getter suggests a 'fire and forget' operation where you can set a value, but you cannot retrieve it later. This might be useful for properties that are used internally but not exposed to the outside. -
What happens if I don't provide a setter for a variable?
If you don't provide a setter for a variable (and it's not initialized using constructor injection or other means), the variable will retain its default value (e.g., 0 for int, null for objects). Furthermore, if the variable is private and lacks a setter, it cannot be modified after object creation, effectively making it read-only after the initial assignment.