final double PI = 3.14159;The final Keyword in Java: Constants, Immutability, and Sealed Design
Direct Answer & Core Concept
When writing Java programs, sometimes you want to say, “This value should not change,” “This method should not be replaced,” or “This class should not be extended.”
Java provides the final keyword for exactly these situations.
The final keyword in Java is used to restrict changes to variables, methods, and classes. It is commonly used for constants, to prevent method overriding, and to stop inheritance.
For beginners, the easiest way to remember it is:
final means you are putting a restriction on further changes.
In this tutorial, you will learn how the final keyword works with variables, methods, and classes. We will also look at constants, final references, immutability, inheritance, common mistakes, and how final is different from Java's newer sealed-class design.
Detailed Explanation & Mechanics
What Is the final Keyword in Java?
The final keyword is a Java keyword used to prevent further modification in certain situations.
It can be applied to:
Variables
Methods
Classes
Parameters
Local variables
Instance variables
Static variables
Its behavior depends on where it is used.
| Usage | What final does |
|---|---|
final variable | Value cannot be reassigned after initialization |
final method | Method cannot be overridden by a subclass |
final class | Class cannot be extended |
final parameter | Parameter cannot be reassigned inside the method |
static final variable | Commonly used to create constants |
So, final does not have only one purpose. Its meaning depends on the Java element where it is declared.
Why Do We Use final in Java?
Imagine you are writing a program for a bank.
Some values should not accidentally change during program execution. For example:
Once PI receives its value, you cannot assign another value to it.
Similarly, suppose a class contains an important method that subclasses should not replace. You can declare that method as final.
final void showAccountRules() {
System.out.println("Account rules");
}And if you have a class that should never be inherited:
final class BankRules {
}The final keyword gives you this type of control.
Types of final in Java
There are three main uses that beginners should learn first:
Final variable
Final method
Final class
Let's understand each one with simple examples.
1. Final Variable in Java
A final variable in Java is a variable whose value cannot be reassigned after it has been initialized.
Example:
class Example {
public static void main(String[] args) {
final int age = 25;
System.out.println(age);
}
}Here, age is declared as final.
You cannot do this later:
age = 30;Java will report a compilation error because a final variable cannot be assigned another value.
Simple idea
Think of a final variable like writing something permanently on a form.
You can fill it once, but you cannot replace it with another value afterward.
Example of final Variable
class Student {
final int rollNumber = 101;
void display() {
System.out.println("Roll Number: " + rollNumber);
}
}The rollNumber cannot be changed after initialization.
Student student = new Student();
student.display();Output:
Roll Number: 101Can a final Variable Be Initialized Later?
Yes.
A final variable does not always have to receive its value on the same line.
For example:
class Student {
final int rollNumber;
Student() {
rollNumber = 101;
}
}Here, rollNumber is declared first and initialized inside the constructor.
Once the constructor assigns the value, it cannot be assigned again.
This is called a blank final variable.
Example:
class Employee {
final int employeeId;
Employee(int id) {
employeeId = id;
}
}Each object can receive its own value during construction:
Employee e1 = new Employee(101);
Employee e2 = new Employee(102);The important point is that each final field must receive a value exactly once along every valid initialization path.
2. static final Variables and Constants in Java
One of the most common uses of final is creating constants.
A Java constant is commonly declared using:
static finalExample:
class MathConstants {
static final double PI = 3.14159;
}Here:
staticmeans the field belongs to the classfinalmeans its value cannot be reassigned
Constants are normally written using uppercase letters.
For example:
static final int MAX_USERS = 100;
static final double TAX_RATE = 0.18;
static final String COMPANY_NAME = "Example";You can access them using the class name:
System.out.println(MathConstants.PI);Why use constants?
Instead of writing the same value repeatedly:
if (users > 100) {
// ...
}you can write:
if (users > MAX_USERS) {
// ...
}This makes the code easier to understand and maintain.
3. Final Method in Java
A final method in Java cannot be overridden by a subclass.
Consider this example:
class Vehicle {
final void start() {
System.out.println("Vehicle is starting");
}
}Now create a child class:
class Car extends Vehicle {
}The Car class inherits the start() method.
However, it cannot replace that method with another implementation.
This would cause a compilation error:
class Car extends Vehicle {
void start() {
System.out.println("Car is starting");
}
}Why?
Because start() was declared as final in the parent class.
Why Use a final Method?
A final method is useful when the parent class provides behavior that subclasses should not change.
For example:
class Payment {
final void validatePayment() {
System.out.println("Payment validation completed");
}
}A subclass can add other functionality, but it cannot override validatePayment().
This can help protect important rules in an inheritance design.
final Method and Method Overriding
To understand final methods, you should first understand method overriding.
Normally, a child class can provide its own implementation of an inherited method.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}class Dog extends Animal {
@Override void sound() {
System.out.println("Dog barks");
}
}Here, Dog overrides sound().
But if the parent declares the method as final:
class Animal {
final void sound() {
System.out.println("Animal makes a sound");
}
}then the child cannot override it.
class Dog extends Animal {
// Compilation error
void sound() {
System.out.println("Dog barks");
}
}So the simple rule is:
A final method can be inherited, but it cannot be overridden.
4. Final Class in Java
A final class in Java cannot be extended.
Example:
final class SecurityManager {
void checkAccess() {
System.out.println("Access checked");
}
}You cannot create a subclass:
class AdminSecurity extends SecurityManager {
}This results in a compilation error because SecurityManager is final.
Why Make a Class final?
Sometimes a class is designed to provide behavior that should not be changed through inheritance.
Declaring the class as final prevents another class from extending it.
For example:
final class Configuration {
void showSettings() {
System.out.println("Application settings");
}
}Now no other class can extend Configuration.
Final Class Example
final class Company {
void display() {
System.out.println("Company information");
}
}public class Main {
public static void main(String[] args) {
Company company = new Company();
company.display();
}
}Output:
Company informationThe class works normally.
The only restriction is that another class cannot extend it.
final Keyword and Inheritance
The final keyword is closely related to inheritance.
There are two important cases:
Final class
A final class cannot be inherited.
final class Parent {
}This is not allowed:
class Child extends Parent {
}Final method
A final method can be inherited, but it cannot be overridden.
class Parent {
final void display() {
System.out.println("Parent method");
}
}A child class can use display(), but cannot provide a new implementation for it.
final Reference Variable in Java
This is one of the areas that often confuses beginners.
Consider:
final StringBuilder builder = new StringBuilder("Hello");The variable builder cannot refer to a different StringBuilder object.
This is not allowed:
builder = new StringBuilder("Java");However, the object itself can still be modified:
builder.append(" Java");
System.out.println(builder);Output:
Hello JavaSo remember:
A final reference cannot be reassigned, but
finaldoes not automatically make the referenced object immutable.
This distinction is very important.
Does final Make an Object Immutable?
No, not by itself.
This is a common Java interview question.
For example:
final List<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");The reference names cannot point to another list:
names = new ArrayList<>();But the existing list can still be modified:
names.add("Priya");Therefore:
final reference ≠ immutable object
Immutability means the object's state cannot be changed after the object has been created.
Java's final keyword can help when designing immutable classes, but it does not automatically make an object immutable.
final Keyword and Immutability
A simple immutable class might look like this:
final class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public int getAge() {
return age;
}
}There are several useful design choices here:
The class is
final, so it cannot be subclassed.The fields are
private.The fields are
final.Values are assigned through the constructor.
There are no setter methods that change the fields.
Example:
User user = new User("Rahul", 25);
System.out.println(user.getName());
System.out.println(user.getAge());Once the object has been created, its name and age fields cannot be reassigned.
Important note
If an immutable class contains a mutable object such as a List, Map, or custom mutable object, simply making the reference final is not enough. The class may also need defensive copying or other techniques to prevent outside code from changing internal state.
final Parameter in Java
The final keyword can also be used with method parameters.
Example:
class Calculator {
void calculate(final int number) {
System.out.println(number);
}
}Inside the method, you cannot reassign number.
This is not allowed:
number = 50;The parameter can still be used normally:
System.out.println(number * 2);Final parameters can make it clear that a method should not change a parameter variable.
final Local Variable
You can also declare a local variable as final.
public class Main {
public static void main(String[] args) {
final int number = 10;
System.out.println(number);
}
}This is not allowed:
number = 20;The restriction applies only to that variable.
final Variable vs Normal Variable
Compare the two examples.
Normal variable
int age = 25;
age = 30;This is valid.
Final variable
final int age = 25;
age = 30;This produces a compilation error.
The difference is simple:
| Normal Variable | Final Variable |
|---|---|
| Can be reassigned | Cannot be reassigned |
| Value may change | Variable cannot receive another value |
| Useful for changing data | Useful for fixed values |
final Class vs final Method
These two uses are easy to mix up.
| Feature | final class | final method |
|---|---|---|
| Can class be extended? | No | Yes |
| Can method be overridden? | All inherited overridable methods cannot be overridden because the class cannot be subclassed | No |
| Main purpose | Prevent inheritance | Prevent method overriding |
| Example | final class User | final void login() |
A final class gives a restriction at the class level.
A final method gives a restriction at the method level.
final vs static final in Java
These are also different.
final
final int age = 30;The variable cannot be reassigned.
static final
static final int MAX_AGE = 100;The field belongs to the class and cannot be reassigned.
static final is therefore commonly used for class-level constants.
Example:
class AppConfig {
static final int MAX_CONNECTIONS = 50;
}Access it like this:
System.out.println(AppConfig.MAX_CONNECTIONS);final vs sealed Classes in Java
The phrase sealed design is important because final is not the only way Java can control inheritance.
A final class says:
No class may extend me.
A sealed class says:
Only the classes I explicitly permit may extend me.
For example:
sealed class Vehicle permits Car, Bike {
}Then:
final class Car extends Vehicle {
}final class Bike extends Vehicle {
}Here, Vehicle controls which classes can directly extend it.
This gives developers more control than simply making a class final.
final vs sealed
final class | +---- No subclass allowedsealed class | +---- Only permitted subclasses allowed | +-----+-----+ | | Car BikeThis is especially useful when designing a controlled class hierarchy.
Is final the Same as Sealed?
No.
They solve related but different problems.
final class
final class Animal {
}No subclass can extend it.
sealed class
sealed class Animal permits Dog, Cat {
}Only the permitted classes can extend it.
A sealed class therefore allows a controlled set of subclasses.
A final class allows none.
final Keyword with Constructors
You cannot declare a constructor as final.
For example, this is invalid:
class Student {
final Student() {
}
}The final keyword is used with methods, variables, and classes, but not constructors.
A constructor cannot be overridden anyway, so making a constructor final would not make sense.
Can a final Method Be Overloaded?
Yes.
final prevents overriding, not overloading.
Example:
class Calculator {
final int add(int a, int b) {
return a + b;
} final double add(double a, double b) {
return a + b;
}
}These methods are overloaded because they have different parameter types.
The methods are still final, so a subclass cannot override either method.
Can a final Method Be Inherited?
Yes.
A final method can be inherited by a child class.
The restriction is that the child cannot override it.
Example:
class Parent {
final void show() {
System.out.println("Parent");
}
}class Child extends Parent {
void display() {
show();
}
}The child can call show().
It simply cannot create another show() implementation with the same method signature as an override.
Can a final Class Have final Methods?
Yes.
But if a class is already final, its methods do not need to be final merely to prevent overriding, because no subclass can exist.
For example:
final class Account {
void display() {
System.out.println("Account");
}
}The class cannot be extended, so display() cannot be overridden through inheritance.
You may still see final methods in final classes for documentation or design clarity, but the class-level restriction already prevents subclassing.
Complete Example of final Keyword in Java
Here is a small example that demonstrates several uses of final together:
final class BankAccount {
static final double MIN_BALANCE = 500.0;
private final int accountNumber;
private final String holderName;
public BankAccount(int accountNumber, String holderName) {
this.accountNumber = accountNumber;
this.holderName = holderName;
} public final void displayAccount() {
System.out.println("Account Number: " + accountNumber);
System.out.println("Account Holder: " + holderName);
System.out.println("Minimum Balance: " + MIN_BALANCE);
}
}public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount(101, "Rahul");
account.displayAccount();
}
}Output:
Account Number: 101Account Holder: RahulMinimum Balance: 500.0This example demonstrates:
final classstatic finalconstantprivate finalfieldsfinalmethodConstructor initialization
Common Mistakes with final Keyword
Beginners often make a few mistakes when learning final.
Mistake 1: Trying to change a final variable
final int number = 10;
number = 20;This is not allowed.
Mistake 2: Thinking final makes every object immutable
final List<String> list = new ArrayList<>();The reference cannot be reassigned, but the list can still change.
Mistake 3: Trying to override a final method
class Parent {
final void show() {
}
}class Child extends Parent {
void show() {
}
}This is not allowed.
Mistake 4: Extending a final class
final class Parent {
}class Child extends Parent {
}This produces a compilation error.
Mistake 5: Confusing final with static
final and static have different purposes.
final int value = 10;means the variable cannot be reassigned.
static int value = 10;means the field belongs to the class.
static final int value = 10;combines both ideas and is commonly used for constants.
Advantages of Using final in Java
The final keyword can make Java code easier to understand and safer to maintain.
1. Protects fixed values
Final variables prevent accidental reassignment.
2. Helps create constants
static final is widely used for class-level constants.
3. Controls inheritance
A final class cannot be extended.
4. Protects important methods
A final method cannot be overridden.
5. Makes design intentions clearer
When another developer sees final, they immediately know that a particular value, method, or class has an intentional restriction.
6. Supports immutable class design
Final fields and final classes are often part of immutable object designs.
Rules of final Keyword in Java
Keep these rules in mind:
A final variable cannot be reassigned after initialization.
A final instance variable must be initialized exactly once.
A final method cannot be overridden.
A final class cannot be extended.
A final parameter cannot be reassigned inside its method.
A final reference cannot point to another object.
A final reference does not automatically make the referenced object immutable.
static finalis commonly used for constants.Constructors cannot be declared
final.A final method can still be overloaded.
A final method can be inherited.
finalandsealedare different ways of controlling inheritance.
Quick Example to Remember final
Think of three situations:
final variable↓Value cannot be reassignedfinal method↓Method cannot be overriddenfinal class↓Class cannot be extendedThis is the easiest way to remember the core idea.
final Keyword in Java: Interview Questions
What is the final keyword in Java?
The final keyword is used to restrict changes. It can be applied to variables, methods, and classes.
What is a final variable in Java?
A final variable can be assigned a value only once. After initialization, it cannot be reassigned.
What is a final method?
A final method cannot be overridden by a subclass.
What is a final class?
A final class cannot be extended or inherited by another class.
Can a final variable be initialized inside a constructor?
Yes. A final instance variable can be initialized in a constructor, provided it is assigned exactly once.
Does final make an object immutable?
No. A final reference cannot be reassigned, but the referenced object may still be mutable.
Can we override a final method?
No. A final method cannot be overridden.
Can we overload a final method?
Yes. Final prevents overriding, not overloading.
Can a final class be inherited?
No. A final class cannot be extended.
Can a constructor be final?
No. Constructors cannot be declared final.
What is the difference between final and static final?
final prevents reassignment of a variable. static final creates a class-level field that cannot be reassigned and is commonly used for constants.
What is the difference between final and sealed in Java?
A final class cannot have any subclasses. A sealed class can have subclasses, but only the classes explicitly permitted by the sealed class can extend it.
final Keyword vs Other Java Keywords
It is useful to understand how final compares with some related Java keywords.
| Keyword | Main purpose |
|---|---|
final | Prevent reassignment, overriding, or inheritance |
static | Make a member belong to the class |
abstract | Define incomplete classes or methods that require implementation |
private | Restrict access to the declaring class |
sealed | Restrict which classes can extend a class |
These keywords can sometimes be used together, but they solve different problems.
When Should You Use final in Java?
Use final when you have a clear reason to prevent a future change.
For example:
Use a final variable when a value should not be reassigned.
final int MAX_RETRY = 3;Use a static final variable when you need a class-level constant.
static final int MAX_USERS = 1000;Use a final method when subclasses should not replace a particular implementation.
final void validate() {
}Use a final class when the class should not participate in inheritance.
final class Utility {
}If you want controlled inheritance rather than completely preventing inheritance, consider a sealed class instead.
Final Keyword in Java: Easy Summary
The final keyword becomes much easier once you remember what it protects.
final | +-----------+-----------+ | | | Variable Method Class | | | No reassignment No No override inheritanceFor variables:
final int x = 10;x cannot be reassigned.
For methods:
final void show() {
}show() cannot be overridden.
For classes:
final class User {
}User cannot be extended.
And for constants:
static final int MAX_USERS = 100;the field is commonly treated as a class-level constant.
The most important thing to remember is that final does not automatically mean immutable. It places a restriction on the variable, method, or class where it is used. For object references, the reference is fixed, while the referenced object's internal state may still be changeable.
Practice Questions
Try answering these before checking the answers.
Question 1
What happens here?
final int x = 10;
x = 20;Answer: The code does not compile because x cannot be reassigned.
Question 2
Can a child class override a final method?
Answer: No.
Question 3
Can a final class be extended?
Answer: No.
Question 4
Does this make the object immutable?
final ArrayList<String> list = new ArrayList<>();Answer: No. The reference cannot be reassigned, but the list can still be modified.
Question 5
Which declaration is commonly used for a Java constant?
static final int MAX_USERS = 100;Answer:static final.
Runnable Code Example: The final Keyword in Java
Java 17+public final class ImmutableToken {
private final String tokenValue;
private final long timestamp;
public ImmutableToken(String tokenValue, long timestamp) {
this.tokenValue = tokenValue;
this.timestamp = timestamp;
} public String getTokenValue() {
return tokenValue;
} public long getTimestamp() {
return timestamp;
} public static void main(String[] args) {
ImmutableToken token = new ImmutableToken("AUTH-9812", System.currentTimeMillis());
System.out.println("Created Token: " + token.getTokenValue());
}
}