- 1Java OOP Introduction
- 2Java Class
- 3Java Class Constructor
- 4Java Class Objects
- 5Java Access Modifiers
- 6Java Static Variables in Classes
- 7Java Static Methods Explained
- 8Java Static Blocks
- 9Java final Variables
- 10Java final Methods
- 11Java final class
- 12Inheritance in Java
- 13Java Method Overriding
- 14Java Abstraction in OOP
- 15Interfaces in Java
- 16Polymorphism in Java
- 17Encapsulation in Java
- 18Java Nested Classes
- 19Java Nested Static Class
- 20Java Anonymous Class
- 21Java Singleton Class
- 22Java Enums
- 23Reflection in Java
Java final class
Prevent Inheritance
In Java, the final
keyword when used with a class, it signals that the class cannot be subclassed or extended.
This concept is especially valuable when you want to design components that are not meant to be changed through inheritance — for example, utility or security-related classes.
Why use a final class?
Marking a class as final
is a purposeful decision. Here’s why developers often do it:
- Security: Prevents malicious subclasses from altering sensitive behavior.
- Immutability: Helps ensure the class remains unchanged, often used in immutable data types.
- Performance: JVM can apply certain optimizations knowing the class won’t be overridden.
Syntax of final class
final class Vehicle {
void displayType() {
System.out.println("This is a vehicle.");
}
}
Here, the Vehicle
class is declared final
, which means:
- You can create objects of it.
- But you cannot extend it using another class.
Attempting to extend a final class (Compilation Error)
final class Vehicle {
void displayType() {
System.out.println("This is a vehicle.");
}
}
class Car extends Vehicle { // ❌ Compilation Error
void showModel() {
System.out.println("This is a sedan.");
}
}
Error: Cannot inherit from final 'Vehicle'
Valid usage of a final class
You can still create objects and call its methods as usual:
final class Logger {
void log(String message) {
System.out.println("LOG: " + message);
}
}
public class Main {
public static void main(String[] args) {
Logger logger = new Logger();
logger.log("Application started");
}
}
LOG: Application started
Common real-world examples of final classes
Java itself defines several final classes:
java.lang.String
— Immutable text.java.lang.Math
— Utility class for mathematical operations.java.lang.System
— System-level utilities.
These classes are final because altering their behavior could break Java’s core functionality or create serious security vulnerabilities.
When should you declare a class as final?
Use final
when:
- You want the class to be non-extendable.
- You are designing a class with complete behavior that shouldn’t be modified.
- You are creating utility/helper classes with static methods only.
Things to remember
- You can’t extend a final class — period.
- Final classes can have final and non-final methods.
- Declaring a class as final does not make its objects immutable — the fields still need to be final or properly encapsulated.
Can a final class have final methods?
Yes! In fact, you can declare methods as final to prevent them from being overridden in subclasses (though in a final class, overriding is impossible anyway).
final class Shape {
final void draw() {
System.out.println("Drawing shape...");
}
}
This is often done to document intention — even if inheritance is blocked, the developer is being explicit that the method shouldn't be touched.
Conclusion
The final keyword, when applied to classes, enforces boundaries, supports clean API design, and aligns with object-oriented principles like encapsulation and immutability.
While it may seem restrictive at first glance, it encourages you to write intentional, safe, and maintainable code.
QUIZ
Question 1:What does marking a class as final
in Java achieve?
Question 2:A final class in Java cannot have methods that are overridden by subclasses.
Question 3:What happens when you try to compile the following code?
final class Vehicle {
void showType() {
System.out.println("Vehicle");
}
}
class Car extends Vehicle {
void showModel() {
System.out.println("Sedan");
}
}
final class Vehicle {
void showType() {
System.out.println("Vehicle");
}
}
class Car extends Vehicle {
void showModel() {
System.out.println("Sedan");
}
}