Java developers often get confused between final
, finally
, and finalize
. These three terms might sound similar, but they serve completely different purposes. If you’ve ever struggled to understand their differences, this guide is for you!
By the end of this post, you’ll have a clear understanding of final vs finally vs finalize in Java and how to use each one correctly. Let’s dive in!
1. What is final
in Java?
The final
keyword in Java is used for constants, method restrictions, and inheritance control. It can be applied to variables, methods, and classes.
a) final
with Variables (Constant Values)
When a variable is declared final
, its value cannot be changed once assigned.
public class FinalVariableExample {
final int MAX_VALUE = 100; // Constant value
void display() {
// MAX_VALUE = 200; // This will cause a compilation error
System.out.println("Max Value: " + MAX_VALUE);
}
}
The MAX_VALUE
variable is declared as final
, so its value cannot be modified.
b) final
with Methods (Prevent Overriding)
A final
method cannot be overridden by subclasses.
class Parent {
final void show() {
System.out.println("This is a final method.");
}
}
class Child extends Parent {
// void show() { // This will cause a compilation error
// System.out.println("Cannot override a final method");
// }
}
The show()
method in the Parent
class is marked final
, preventing the Child
class from overriding it.
c) final
with Classes (Prevent Inheritance)
A class declared as final
cannot be extended.
final class FinalClass {
void display() {
System.out.println("This is a final class.");
}
}
// class SubClass extends FinalClass { // This will cause a compilation error
// }
The FinalClass
cannot be extended by any subclass.
2. What is finally
in Java?
The finally
block in Java is used to ensure that important code executes, regardless of exceptions. It is primarily used with try-catch
blocks to handle exceptions.
public class FinallyExample {
public static void main(String[] args) {
try {
int result = 10 / 0; // This will cause an exception
} catch (ArithmeticException e) {
System.out.println("Exception caught: " + e.getMessage());
} finally {
System.out.println("Finally block executed!");
}
}
}
Output:
Exception caught: / by zero
Finally block executed!
The finally
block runs no matter what happens in the try-catch block. This is useful for closing resources like database connections or file streams.
3. What is finalize()
in Java?
The finalize()
method is used for garbage collection. It is called by the Garbage Collector before an object is destroyed to perform cleanup operations.
class FinalizeExample {
protected void finalize() {
System.out.println("Finalize method called before garbage collection.");
}
public static void main(String[] args) {
FinalizeExample obj = new FinalizeExample();
obj = null; // Making object eligible for garbage collection
System.gc(); // Requesting garbage collection
System.out.println("End of main method.");
}
}
Output (may vary depending on JVM execution):
End of main method.
Finalize method called before garbage collection.
- The
finalize()
method is called before an object is garbage collected but not guaranteed to execute immediately or at all. - Calling
System.gc()
only suggests garbage collection to the JVM, but it does not force it. - Due to unpredictability and performance issues,
finalize()
has been deprecated in Java 9 and removed (marked as remove) in Java 18.
Alternatives to finalize()
:
- Try-with-resources (
AutoCloseable
) – For handling resources like files, sockets, and streams. java.lang.ref.Cleaner
(Java 9+) – A more reliable way to register cleanup actions when objects become unreachable.
Important Note:
The use of finalize()
is strongly discouraged in modern Java programming. Developers should use explicit resource management instead of relying on garbage collection for cleanup.
Final vs Finally vs Finalize in Java: Key Differences
Feature | final | finally | finalize() |
---|---|---|---|
Usage | Variable, method, or class modifier | Block in exception handling | Method in garbage collection |
Effect | Restricts variable reassignment, method overriding, and class inheritance | Ensures execution of critical code | Allows cleanup before object removal |
Execution | Compile-time | Always runs after try-catch | Called by garbage collector |
Purpose | Restriction | Code execution assurance | Cleanup |
When to Use Final, Finally, and Finalize?
- Use
final
when you want to create constants, prevent method overriding, or restrict class inheritance. - Use
finally
when you need to execute important code regardless of exceptions, like closing resources. - Use
finalize()
only if you need to clean up resources before garbage collection, though it is now discouraged.
Conclusion
Understanding final vs finally vs finalize in Java is crucial for writing efficient and error-free Java programs. While final
is used for constants, method restrictions, and inheritance prevention, finally
ensures essential code execution, and finalize()
helps with garbage collection (though deprecated in Java 9+).