Explain final keyword in Java.
The `final` keyword in Java is a non-access modifier that restricts modification, overriding, or inheritance, depending on where it's applied. It signifies immutability or a lack of extensibility.
Purpose of `final`
The final keyword in Java is used to define an entity that cannot be reassigned (for variables), overridden (for methods), or inherited (for classes). It's a powerful tool for ensuring immutability and enforcing design constraints, helping to create more robust and secure code.
Applying `final`
final can be applied to variables, methods, and classes, each with a distinct effect.
`final` Variables
When applied to a variable, final makes it a constant, meaning its value can only be assigned once. For primitive types, this means the value itself cannot change. For reference types, it means the reference itself cannot be reassigned to point to a different object, although the internal state of the referenced object can still be modified (unless the object itself is immutable).
public class FinalVariableExample {
// Compile-time constant
private final int MAX_VALUE = 100;
// Blank final variable, must be initialized in constructor
private final String API_KEY;
public FinalVariableExample(String apiKey) {
this.API_KEY = apiKey; // Assigned once
// MAX_VALUE = 200; // Compile-time error: cannot assign a value to final variable MAX_VALUE
}
public void demonstrate() {
final int localConstant = 50;
// localConstant = 60; // Compile-time error
System.out.println("Max Value: " + MAX_VALUE);
System.out.println("API Key: " + API_KEY);
final StringBuilder sb = new StringBuilder("Hello");
// sb = new StringBuilder("World"); // Compile-time error: cannot assign a value to final variable sb
sb.append(" World"); // This is allowed, the object's state can change
System.out.println("StringBuilder: " + sb);
}
}
`final` Methods
A final method cannot be overridden by any subclass. This is useful for preventing unwanted modifications to core logic, ensuring that a method's implementation remains consistent across the class hierarchy. It's often used in design patterns or utility classes where specific behavior should not be altered.
class Parent {
public final void display() {
System.out.println("This is a final method in Parent.");
}
public void greet() {
System.out.println("Hello from Parent!");
}
}
class Child extends Parent {
// @Override
// public void display() { // Compile-time error: cannot override final method from Parent
// System.out.println("This is a display method in Child.");
// }
@Override
public void greet() { // Allowed, greet is not final
System.out.println("Hello from Child!");
}
}
`final` Classes
When a class is declared as final, it cannot be extended or subclassed. This means no other class can inherit from it. final classes are inherently immutable (if their fields are also final and properly handled) and are often used for security reasons, to prevent malicious subclasses, or to create utility classes with fixed behavior, like String, Integer, and other wrapper classes in Java's standard library.
final class ImmutablePoint {
private final int x;
private final int y;
public ImmutablePoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
// No setters, ensuring immutability
}
// class AnotherPoint extends ImmutablePoint { // Compile-time error: cannot inherit from final ImmutablePoint
// // ...
// }
Summary
finalvariables: Can be assigned only once, making them constants. For reference types, the reference cannot change, but the object's state might (unless the object itself is immutable).finalmethods: Cannot be overridden by subclasses, ensuring consistent behavior.finalclasses: Cannot be extended or inherited, preventing modification of their behavior through subclassing.- Used for immutability, security, and enforcing design constraints.