Top Java Interview Questions On Final Class
Answering Popular Java Questions On Final Class
Consider becoming a free or paid subscriber and support the work :)
Still not convinced? Check out the details of the past work
What is a final class in Java?
A final class is a class that cannot be subclassed (i.e, no other class can extend it )
We declare it using the `final` keyword.
example:
final class Transaction { }key purpose is to freeze the inheritance hierarchy for that class.
What does the final keyword mean in Java?
The `final` keyword in Java has 3 distinct meanings depending on where it is applied - to a method, variable, or class. The final keyword prevents change in some form. It forces non-modifiability.
`final` variable: value cannot change
final int MAX_USERS = 100;MAX_USERS = 200; // Compile error
Notes: for objects, references cannot be changed, but internal state can be modified
`final` method: cannot be overridden
A final method can’t be overridden in a subclass.class A { public final void process() { } } class B extends A { @Override public void process() { } // Compile error }`final` class: cannot be inherited
A final class cannot be extended.
final class PaymentGateway { } class MyGateway extends PaymentGateway { } // Compile error
Why should we use a final class? Explain real-world examples.
Immutable Value Object
In fintech, a
Moneyobject must not be subclassed because:Currencies must follow strict rules
Arithmetic operations must be safe
Precision rules must not be changed
Rounding behavior must be consistent
Why final? Prevents someone from doing
Security-sensitive Component
A class that executes OS commands inside a controlled environment:
class UnsafeProcessRunner extends SafeProcessRunner { @Override public int run(String command) { return Runtime.getRuntime().exec(command).waitFor(); // SECURITY RISK } }This breaks the entire security model.
Domain-Driven Design (DDD) — Aggregates That Must Not Be Extended
Example: orderId, productId
These are identity objects used across the system.
public final class OrderId { private final UUID id; public OrderId(UUID id) { this.id = id; } }Cache Keys / Hash Keys (Prevent breaking hashCode contract)
Suppose we have a Redis or Caffeine cache key:
If someone subclasses and overrides
equals()→ our cache becomes inconsistent with hard-to-debug bugs.Some other use cases:
DTO’s in microservices
Utility classes
Client wrappers
Logging adapters
Does the final class mean immutability? Explain with examples.
No. A final class does not automatically mean immutability. It only means we cannot inherit/subclass it.
It says nothing about whether the object’s internal state can change. A final class prevents inheritance.
An immutable class prevents its state from changing. These are different things.
A final class can still be mutable.
Example 1:
public final class User {
private String name;
private int age;
public void setName(String name) { this.name = name; }
public void setAge(int age) { this.age = age; }
}
The user class is
final→ cannot be subclassedBut the object is clearly mutable → state changes through setters
User user = new User();
user.setAge(1);
user.setName(”a”);
System.out.println(user.toString());
user.setName(”b”);
System.out.println(user.toString());
-------------------------------------
User{name=’a’, age=1}
User{name=’b’, age=1}Example 2:
public final class Customer {
private List<String> addresses = new ArrayList<>();
public List<String> getAddresses() {
return addresses;
}
}Even without setters:
Customer c = new Customer();
c.getAddresses().add(”Toronto”);
c.getAddresses().add(”Vancouver”);Still mutable, because callers can mutate the returned list.
In order to have a final class immutable, we need to do the following:
Make a class final
Define all fields final
No setters
No expose mutable internals
Make defensive copy
Share some example classes from the JDK if you are aware of them
String
Wrapper classes
IntegerLongDoubleFloatShortByteCharacter,Boolean
java.timeAPI classesLocalDateLocalTimeLocalDateTimeInstantDurationPeriod
When should we avoid using a final class?
Declaring a class as final prevents subclassing, which can be too restrictive in many situations. We should avoid it when:
Expect extensibility
If the class is part of a framework, SDK, or library, clients may need to extend it.
Making it final prevents useful subclassing and limits flexibility.
Example:
Spring Boot classes likeAbstractControllerorJpaRepositoryare not final because users often extend them.We want polymorphic behavior
Subclassing is necessary for polymorphism.
If clients need to override behavior, final is inappropriate.
Utility Classes vs Core Domain Classes
Utility classes like
Math→ final (good)Core domain abstractions (services, processors, controllers) → usually avoid final, unless we want immutability or security guarantees.
When Using Frameworks That Rely on Proxies
Frameworks like Spring rely on subclassing/proxying (
CGLIB) for AOP, transactions, and caching.If a class is final, proxies cannot be created → annotations like
@Transactionalmay fail.
How final class relates to sealed class introduced in Java 17
final class:
Cannot be subclassed at all.
The class hierarchy ends here.
Example: String, Integer, LocalDate.
sealed class (Java 17+):
Can be subclassed, but only by a restricted set of classes explicitly declared in permits.
Provides controlled extensibility.
Example:
public sealed class Shape permits Circle, Rectangle { } public final class Circle extends Shape { } public non-sealed class Rectangle extends Shape { }They are different concepts, but at the property level, a final class is essentially a sealed class with zero permitted subclasses.
Consider becoming a free or paid subscriber and support the work :)
Still not convinced? Check out the details of the past work








The Spring proxy trap is super underrated. I've debugged way too many cases where someone marked a service class as final and then wondered why @Transactional stopped working. The error messages don't always make it obvious either, you just get weird behavior where transactions don't rollback. Would be cool if the compiler or IDE could warn about this combo.