Difference Between final, finally, and finalize() in Java
Even though final, finally, and finalize() sound similar, they serve completely different purposes in Java.
1. final (Keyword)
✅ Purpose: Used for constants, preventing inheritance, and preventing method overriding.
✅ Usage: Applied to variables, methods, and classes.
✅ Compilation-Level Restriction (Checked at compile-time).
Usage of final
| Context | Meaning |
|---|---|
final variable | Value cannot be changed (constant). |
final method | Cannot be overridden in subclasses. |
final class | Cannot be extended (inherited). |
Example 1: final Variable (Constant)
class Example {
final int MAX = 100; // Constant
void changeMax() {
// MAX = 200; // ❌ Compilation Error: Cannot modify final variable
}
}
Example 2: final Method (Cannot be Overridden)
class Parent {
final void show() {
System.out.println("Final method in Parent");
}
}
class Child extends Parent {
// void show() { } ❌ Compilation Error: Cannot override final method
}
Example 3: final Class (Cannot be Inherited)
final class Vehicle { }
// class Car extends Vehicle { } ❌ Compilation Error: Cannot extend final class
2. finally (Block in Exception Handling)
✅ Purpose: Ensures a block of code always executes after a try-catch block, even if an exception occurs.
✅ Usage: Used in exception handling (try-catch-finally).
✅ Runtime Execution (Checked at runtime).
Example: finally Always Executes
public class FinallyExample {
public static void main(String[] args) {
try {
int result = 10 / 0; // ❌ Exception occurs (ArithmeticException)
} catch (ArithmeticException e) {
System.out.println("Exception caught: " + e.getMessage());
} finally {
System.out.println("This will always execute!");
}
}
}
Output:
Exception caught: / by zero
This will always execute!
✔ Even if an exception occurs, finally runs!
Example: finally Executes Even If return Is Used
public class FinallyExample {
static int test() {
try {
return 10;
} finally {
System.out.println("Finally block executed!");
}
}
public static void main(String[] args) {
System.out.println("Return value: " + test());
}
}
Output:
Finally block executed!
Return value: 10
✔ finally executes even after return.
3. finalize() (Method for Garbage Collection)
✅ Purpose: Called by the Garbage Collector (GC) before an object is removed from memory.
✅ Usage: Used for resource cleanup before an object is destroyed.
✅ Deprecated in Java 9+ (Not recommended).
Example: finalize() Method
class Example {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize method called before object is destroyed");
}
public static void main(String[] args) {
Example obj = new Example();
obj = null; // Eligible for GC
System.gc(); // Request Garbage Collection
}
}
Output (Timing Not Guaranteed)
Finalize method called before object is destroyed
✔ finalize() is unreliable because the GC does not guarantee when it runs.
4. Key Differences
| Feature | final | finally | finalize() |
|---|---|---|---|
| Type | Keyword | Block | Method |
| Used For | Constants, inheritance restriction | Ensuring execution in exception handling | Garbage collection cleanup |
| Execution Time | Compile-time | Runtime (Exception Handling) | Runtime (Before GC removes object) |
| Can Be Overridden? | No (applies to classes, methods, variables) | Not applicable | Yes (from Object class) |
| Recommended in Modern Java? | ✅ Yes | ✅ Yes | ❌ No (Deprecated in Java 9) |
5. Final Summary
| Concept | Key Idea |
|---|---|
final | Prevents modification (variables), overriding (methods), and inheritance (classes). |
finally | Ensures cleanup code always executes after try-catch. |
finalize() | Runs before an object is garbage collected (deprecated). |