The final Keyword in Java

The final
keyword in Java is a non-access modifier that provides restrictions on classes, methods, and variables. It's one of the most important keywords for controlling inheritance, method overriding, and variable reassignment.
1. final
with Variables
When a variable is declared as final
, it becomes a constant and cannot be reassigned after initialization.
Instance Variables
public class Student {
private final String studentId;
private final int rollNumber = 101; // initialized at declaration
public Student(String id) {
this.studentId = id; // must be initialized in constructor
}
// studentId cannot be changed after this point
}
Local Variables
public void demonstrateFinalVariables() {
final int x = 10;
// x = 20; // Compilation error - cannot reassign
final List<String> names = new ArrayList<>();
names.add("John"); // This is allowed - we're modifying the object
// names = new ArrayList<>(); // This would cause compilation error
}
Static Final Variables (Constants)
public class Constants {
public static final double PI = 3.14159;
public static final String APP_NAME = "MyApplication";
// Blank final static variable - must be initialized in static block
public static final String DATABASE_URL;
static {
DATABASE_URL = "jdbc:mysql://localhost:3306/mydb";
}
}
2. final
with Methods
A final
method cannot be overridden by subclasses.
class Parent {
public final void displayInfo() {
System.out.println("This method cannot be overridden");
}
public void regularMethod() {
System.out.println("This can be overridden");
}
}
class Child extends Parent {
// This would cause compilation error
// public void displayInfo() { } // Cannot override final method
@Override
public void regularMethod() {
System.out.println("Overridden method");
}
}
Real-world Example
public abstract class Shape {
protected double area;
// Template method pattern - algorithm shouldn't be changed
public final double getAreaWithBorder(double borderWidth) {
double baseArea = calculateArea();
double borderArea = calculateBorderArea(borderWidth);
return baseArea + borderArea;
}
// These can be overridden by subclasses
protected abstract double calculateArea();
protected abstract double calculateBorderArea(double borderWidth);
}
3. final
with Classes
A final
class cannot be extended (subclassed).
public final class ImmutablePerson {
private final String name;
private final int age;
public ImmutablePerson(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
// This would cause compilation error
// class ExtendedPerson extends ImmutablePerson { }
Famous Final Classes in Java
String
classAll wrapper classes (
Integer
,Double
,Boolean
, etc.)LocalDate
,LocalTime
,LocalDateTime
4. final
with Parameters
Method parameters can be declared as final
to prevent reassignment within the method.
public void processData(final String data, final List<Integer> numbers) {
// data = "new value"; // Compilation error
// numbers = new ArrayList<>(); // Compilation error
// But you can still modify the object's state
numbers.add(42); // This is allowed
System.out.println("Processing: " + data);
}
5. Blank Final Variables
Final variables that are not initialized at the point of declaration.
public class BlankFinalExample {
private final String name; // blank final instance variable
private static final String APP_VERSION; // blank final static variable
// Instance blank final must be initialized in constructor
public BlankFinalExample(String name) {
this.name = name;
}
// Static blank final must be initialized in static block
static {
APP_VERSION = "1.0.0";
}
}
6. final
and Collections
public class CollectionExample {
private final List<String> items = new ArrayList<>();
public void addItem(String item) {
items.add(item); // Allowed - modifying content
}
public void clearItems() {
items.clear(); // Allowed - modifying content
}
// This method would cause compilation error
// public void replaceList() {
// items = new ArrayList<>(); // Cannot reassign final variable
// }
public List<String> getItems() {
return Collections.unmodifiableList(items); // Return immutable view
}
}
7. Performance Implications
The final
keyword can provide performance benefits:
public class PerformanceExample {
private static final String CONSTANT = "Hello"; // JVM can optimize
public final void criticalMethod() {
// JVM can inline this method for better performance
System.out.println("Critical operation");
}
}
Interview Questions and Answers
Beginner Level
Q1: What is the final
keyword in Java? A: The final
keyword is a non-access modifier that restricts modification. It can be applied to variables (making them constants), methods (preventing overriding), and classes (preventing inheritance).
Q2: Can you change the value of a final variable? A: No, once a final variable is initialized, its reference cannot be changed. However, if it's an object reference, the object's internal state can still be modified.
Q3: What happens if you don't initialize a final variable? A: For instance variables, you must initialize them either at declaration or in the constructor. For static variables, you must initialize them at declaration or in a static block. Otherwise, you'll get a compilation error.
Intermediate Level
Q4: What is the difference between final, finally, and finalize? A:
final
: A keyword for restrictions (variables, methods, classes)finally
: A block that executes after try-catch, regardless of exceptionsfinalize()
: A method called by garbage collector before object destruction (deprecated in Java 9+)
Q5: Can a final method be overloaded? A: Yes, final methods can be overloaded but cannot be overridden. Overloading creates new methods with different signatures, while overriding replaces the parent method implementation.
class Example {
public final void process(String data) { }
public final void process(int number) { } // Overloading is allowed
}
Q6: Why is the String class final in Java? A: String is final to ensure immutability and security. If String could be extended, someone could create a malicious subclass that changes behavior, potentially compromising security in areas like file paths, URLs, or database connections.
Advanced Level
Q7: Explain blank final variables with an example. A: Blank final variables are final variables declared without initialization. They must be initialized exactly once before use.
public class BlankFinalDemo {
private final int value; // blank final
public BlankFinalDemo(int val) {
if (val > 0) {
this.value = val; // initialization in constructor
} else {
this.value = 1; // must initialize in all code paths
}
}
}
Q8: Can you have a final abstract method or final abstract class? A: No, this is contradictory. Abstract methods are meant to be overridden, while final methods cannot be overridden. Similarly, abstract classes are meant to be extended, while final classes cannot be extended.
Q9: What is the effectively final concept in Java 8? A: A variable is effectively final if it's not declared final but is never reassigned after initialization. This is important for lambda expressions and inner classes.
public void demonstrateEffectivelyFinal() {
String message = "Hello"; // effectively final
// message = "Hi"; // if uncommented, it's no longer effectively final
Runnable r = () -> System.out.println(message); // works because message is effectively final
}
Q10: How does final
affect inheritance and polymorphism? A: Final classes cannot be extended, breaking inheritance chains. Final methods cannot be overridden, limiting polymorphic behavior. However, final variables don't affect inheritance directly but ensure data integrity.
Tricky Questions
Q11: What will be the output of this code?
class Parent {
public final void display() {
System.out.println("Parent display");
}
}
class Child extends Parent {
public void display() { // Will this compile?
System.out.println("Child display");
}
}
A: This code will not compile because you cannot override a final method. The compiler will throw an error.
Q12: Is it possible to modify a final object? A: Yes, you can modify the internal state of a final object reference, but you cannot reassign the reference itself.
final List<String> list = new ArrayList<>();
list.add("item"); // Allowed - modifying object state
// list = new ArrayList<>(); // Not allowed - reassigning reference
The final
keyword is crucial for creating immutable objects, ensuring security, enabling certain optimizations, and controlling inheritance hierarchies. Understanding its various applications will help you write more robust and secure Java code.
Subscribe to my newsletter
Read articles from Karam Srikanth Reddy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Karam Srikanth Reddy
Karam Srikanth Reddy
Don't hope that events will turn out the way you want, welcome events whichever way they happen: this is the path to peace. Epictetus