Back to Java
2025-12-085 min read

final

Learn final step by step with clear examples and exercises.

Title: Mastering the Final Keyword in Java - A full guide

Why This Matters

In this tutorial, we will delve deep into the final keyword in Java, an essential concept for any serious Java programmer. The final keyword is used to create constants, limit method overriding, and ensure object immutability - all crucial skills for tackling real-world coding challenges and interview questions.

Prerequisites

Before we dive into the core concept of the final keyword, it's important that you have a solid understanding of the following:

  1. Basic Java syntax (variables, methods, classes)
  2. Object-oriented programming concepts (inheritance, polymorphism)
  3. Variables and constants
  4. Method overriding
  5. Exception handling
  6. Interfaces
  7. Abstract classes
  8. Static members
  9. Access modifiers
  10. Java collections framework

Core Concept

What is the final keyword in Java?

The final keyword in Java serves multiple purposes: creating constants, limiting method overriding, and ensuring object immutability. Here's a breakdown of each use case:

Constants

In Java, you can use the final keyword to declare constants, which are variables that cannot be changed once assigned. To create a constant variable, simply prefix it with the final keyword and assign a value:

public static final double PI = 3.141592653589793;

Method Overriding

By default, Java allows subclasses to override methods from their parent classes. However, you can use the final keyword on a method to prevent it from being overridden by any subclass:

public final void myFinalMethod() {
// ...
}

Object Immutability

You can also declare a class as final to ensure that no subclasses can be created. This is useful for creating immutable objects, which cannot be modified once they're instantiated:

public final class ImmutableClass {
private final String name;
private final int age;

public ImmutableClass(String name, int age) {
this.name = name;
this.age = age;
}

// ...
}

When to use the final keyword?

The final keyword is particularly useful in the following scenarios:

  1. Declaring constants, such as mathematical or physical constants, to ensure their values cannot be changed.
  2. Preventing method overriding when it would lead to unintended behavior or break encapsulation.
  3. Creating immutable objects to improve thread safety and prevent accidental modification.
  4. Declaring a method as final if it provides the intended behavior for all possible subclasses, thus preventing unnecessary overrides.
  5. Declaring a class as final when it represents an atomic unit that should not be extended or modified by other classes.

Worked Example

Let's create a simple example that demonstrates the use of the final keyword in each of its contexts:

public class FinalExample {
public static void main(String[] args) {
// Constants
final double PI = 3.141592653589793;
System.out.println("Value of PI: " + PI);

// Attempt to change the constant - this will result in a compile-time error
// PI = 3.141592653589794;

// Method overriding
class MyClass {
public void myMethod() {
System.out.println("Default method");
}
}

final class MyFinalClass extends MyClass {
@Override
public final void myMethod() {
// This method cannot be overridden by any subclass
System.out.println("Final method");
}
}

MyClass obj = new MyClass();
obj.myMethod(); // Output: Default method

MyFinalClass finalObj = new MyFinalClass();
finalObj.myMethod(); // Output: Final method

// Immutable objects
final String immutableName = "John Doe";
System.out.println("Immutable name: " + immutableName);
// Attempt to change the immutable object - this will result in a compile-time error
// immutableName = "Jane Smith";

// Using final with exception handling and interfaces
public static void main(Exception e) {
if (e instanceof ArithmeticException) {
throw new RuntimeException("Cannot divide by zero", e);
}
}

interface MyInterface {
void myMethod();
}

final class MyFinalClass implements MyInterface {
@Override
public final void myMethod() {
// Implementation of the interface method that cannot be overridden
System.out.println("Implemented method");
}
}
}

Common Mistakes

  1. Forgetting the final keyword when declaring constants, leading to unintended changes later on.
  2. Using the final keyword on methods that should be overridable, causing issues with polymorphism and inheritance.
  3. Attempting to modify immutable objects or their final variables, resulting in compile-time errors.
  4. Misusing the final keyword by declaring classes as final when they don't need to be (e.g., mutable classes that should be overridden).
  5. Failing to understand the difference between constants and immutable objects, leading to inappropriate use of the final keyword.
  6. Using final with non-primitive types without careful consideration, as it can lead to issues with memory management and object creation.
  7. Declaring a method as both final and synchronized, which may result in unexpected behavior due to the interaction between these modifiers.

Practice Questions

  1. Write a Java program that declares a final variable for the value of π (pi) and uses it in a calculation involving an exception.
  2. Create a class Shape with a method area(). Make the method final to prevent any subclass from overriding it, but create a subclass Square that extends Shape and provides its own implementation of the area() method using inheritance and polymorphism.
  3. Write a Java program that demonstrates the use of immutable objects by creating an immutable Person class with final variables for name, age, and address.
  4. (Bonus) Create a final method that throws an exception if its argument is less than zero.
  5. (Bonus) Declare an interface MyInterface with a final method that returns the Fibonacci sequence up to a given number. Implement this interface in a class Fibonacci using recursion.

FAQ

  1. Can I change the value of a constant declared as final?
  • No, constants declared as final cannot be changed once assigned. Any attempt to do so will result in a compile-time error.
  1. Why should I use the final keyword on methods?
  • Using the final keyword on methods can help prevent unintended overriding, maintain encapsulation, and ensure that certain methods behave consistently across all instances of a class.
  1. What happens if I declare a class as final but it has mutable fields or methods?
  • Declaring a class as final does not prevent its fields or methods from being modified. However, it does prevent any subclass from extending the class and potentially overriding its methods.
  1. Can I make a method private final to ensure it cannot be overridden by any class?
  • Yes, you can make a method private final to achieve this. However, it will only be accessible within the defining class and cannot be overridden by any subclass.
  1. Can I use the final keyword with interfaces or abstract classes?
  • No, the final keyword cannot be applied to interfaces or abstract classes directly. However, you can create final implementations of interfaces or override abstract methods in a final class.
  1. What are some best practices for using the final keyword in Java?
  • Use the final keyword judiciously, as overuse can make code less flexible and harder to maintain. Consider using it when declaring constants, limiting method overriding, or creating immutable objects. Always ensure that your use of the final keyword aligns with the intended behavior and design of your program.
final | Java | XQA Learn