Java, as an object-oriented programming language, is rich in features that promote security, maintainability, and performance. Among the many keywords and constructs provided, final finally finalize in Java often confuse beginners and even intermediate developers due to their similar names but very different functionalities.
Regardless of their resembles, these three terms hold different meanings in Java and cater to different areas of the programming lifecycle.
Here, the Bmwatch team has elaborated on the differences of final finally finalize in java to clear the air regarding this terminology to help the beginner coders.
So, let’s get started.
The final Keyword in Java
The final keyword in Java is a non-access modifier used for variables, methods, and classes. Its main purpose is to restrict further modification.
Final Variables
When a variable is declared final, its value cannot be changed once it has been assigned. It effectively makes the variable a constant.
For instance
final int age = 25;
age = 30; // Compilation error
In the example above, trying to reassign a value to age after it’s declared final results in a compile-time error. This is particularly useful when you want to define constants or ensure that a particular value remains unchanged throughout the execution.
Java conventionally uses uppercase letters with underscores for final variables that are constants.
For instance
final double PI = 3.14159;
final String COMPANY_NAME = “OpenAI”;
Final with Reference Types
When a reference variable is declared final, it cannot point to a different object. However, the contents of the object it refers to can still be modified (if the object itself is mutable).
final List<String> names = new ArrayList<>();
names.add(“Alice”); // Allowed
names = new ArrayList<>(); // Not allowed
This distinction is crucial for understanding the behavior of collections or custom objects used in immutable contexts.
Final Methods
When a method is marked final, it cannot be overridden by subclasses. This is useful for maintaining the integrity of method behavior in inheritance hierarchies.
class Parent {
final void display() {
System.out.println(“Final method”);
}
}
class Child extends Parent {
void display() { // Compilation error
System.out.println(“Trying to override”);
}
}
This ensures that subclasses cannot change the behavior of critical methods, which can be especially useful for security-sensitive operations or for providing a consistent API.
Final Classes
A class declared final cannot be subclassed. This is generally done for security reasons or to prevent misuse of certain classes.
final class Vehicle {
void start() {
System.out.println(“Vehicle started”);
}
}
class Car extends Vehicle { // Compilation error
// Cannot inherit from final class
}
Some well-known final classes in Java include String, Integer, and LocalDate. This finality ensures their immutability and reliability in a multithreaded environment.
Best Practices with final
- Use final for constants to ensure they aren’t changed elsewhere.
- Mark methods final to lock down logic you don’t want subclasses to alter.
- Declare classes final when you’re creating utility classes or want immutability.
The finally Block in Java
Unlike final, the finally block is used in the context of exception handling. In Java, a try-catch structure allows the developer to catch exceptions and handle them.
However, when you need to execute some code regardless of whether an exception occurs or not, that’s where finally comes into play.
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println(“Cannot divide by zero”);
} finally {
System.out.println(“This will always execute”);
}
Use Cases for finally
The finally block is primarily used for resource cleanup, such as closing file streams, database connections, or releasing other system resources.
FileInputStream file = null;
try {
file = new FileInputStream(“data.txt”);
// Read file
} catch (IOException e) {
System.out.println(“File not found”);
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Even if an exception occurs during the file read, or even if it doesn’t, the finally block will execute and ensure the file stream is closed, thereby preventing resource leaks.
finally vs return
A common question is: What if there’s a return statement in the try or catch block? Will the finally block still execute?
Yes—it will. Here’s an example:
public int getValue() {
try {
return 10;
} finally {
System.out.println(“Inside finally block”);
}
}
The output will be:
Inside finally block
Even though the method returns a value, the finally block still executes before the method concludes. However, if the JVM shuts down or is forcefully exited (e.g., using System.exit(0)), then the finally block might not execute.
finally Without catch
Interestingly, a finally block can be used without a catch block, provided a try block is present.
try {
// some code
} finally {
// cleanup code
}
This can be useful when you don’t need to handle exceptions but still want to ensure that some code is executed regardless of what happens in the try block.
The finalize() Method in Java
The finalize() method in Java is part of the object cleanup mechanism and belongs to the java.lang.Object class. It is called by the Garbage Collector (GC) before the object is actually removed from memory, giving the object a last chance to release resources or perform other cleanup activities.
protected void finalize() throws Throwable {
try {
System.out.println(“finalize method called”);
} finally {
super.finalize();
}
}
When is finalize() Called?
The finalize() method is not called manually. It is invoked by the GC thread when it determines there are no more references to the object.
public class Demo {
public void finalize() {
System.out.println(“Demo object is being garbage collected”);
}
public static void main(String[] args) {
Demo obj = new Demo();
obj = null;
System.gc();
}
}
You may see the output:
Demo object is being garbage collected
However, it is not guaranteed. The JVM does not promise that finalize() will be called promptly or at all, depending on system load and GC behavior.
Why finalize() Is Deprecated
Starting with Java 9, the finalize() method was deprecated, and in Java 18, it was fully removed from the standard specification. The reasons for this include:
- Unpredictability: You don’t know when it will execute.
- Performance issues: Finalizable objects delay garbage collection.
- Security concerns: Can lead to resurrection of objects, which can be exploited.
- Better alternatives exist, such as try-with-resources.
Better Alternatives: try-with-resources
Since Java 7, the try-with-resources statement has provided a more robust way to manage resources. Any object that implements AutoCloseable (or Closeable) can be used.
try (FileReader reader = new FileReader(“file.txt”)) {
// Read from the file
} catch (IOException e) {
e.printStackTrace();
}
This ensures that reader.close() is called automatically, removing the need for a finally block or finalize() method.
The Distinctions at a Glance
Let’s recap the key differences among final finally finalize in java
Feature | final | finally | finalize() |
Type | Keyword | Block | Method |
Purpose | Prevent modification | Execute cleanup code | Cleanup before GC |
Usage | Variables, Methods, Classes | Try-catch block | Overridden from Object class |
Control | Compile-time | Run-time | Run-time (by GC) |
Deprecated? | No | No | Yes (from Java 9 onwards) |
Real-World Scenarios and Best Practices
When to Use final
- When declaring constants.
- When writing immutable classes.
- To enforce method or class restrictions in secure APIs.
When to Use finally
- Always release resources like files, sockets, and database connections.
- Use finally with care when multiple return statements are involved.
When Not to Use finalize()
- Avoid overriding finalize() in modern Java applications.
- Use try-with-resources or implement AutoCloseable for clean resource handling.
Conclusion: final finally finalize in java
Although final finally finalize in java () share a common root in their names, their roles in Java are distinctly separate and non-overlapping.
The final keyword is a tool for defining constants and sealing methods and classes. The finally block is vital for guaranteed code execution, especially in exception handling scenarios.
Meanwhile, finalize() once provided a safety net for resource release before garbage collection but is now considered outdated and unreliable.
Understanding these terms is not just about memorizing syntax, but about writing cleaner, safer, and more efficient code.
Whether you’re an aspiring developer preparing for interviews or a professional polishing your skills, having a solid grasp of these keywords will elevate your Java proficiency.
For more, continue to read at Bmwatch.co.uk