Final, Finally, and Finalize in Java
Java provides the keywords final, finally, and finalize, each serving a distinct purpose. Below is a detailed explanation of their usage, differences, and examples.
1. Final:
- Definition:
- The
finalkeyword is used to apply restrictions on classes, methods, and variables.
- The
- Usage:
- Final Variable:
- A
finalvariable’s value cannot be changed once assigned.
- A
- Final Variable:
public class FinalVariableExample {
public static void main(String[] args) {
final int CONSTANT = 100;
// CONSTANT = 200; // Error: Cannot reassign a final variable
System.out.println(CONSTANT);
}
}
- Final Method:
- A
finalmethod cannot be overridden by subclasses.
- A
class Parent {
public final void display() {
System.out.println("This is a final method.");
}
}
class Child extends Parent {
// Error: Cannot override the final method from Parent
// public void display() { ... }
}
- Final Class:
- A
finalclass cannot be subclassed.
- A
public final class FinalClass {
public void display() {
System.out.println("This is a final class.");
}
}
// Error: Cannot subclass a final class
// class SubClass extends FinalClass {}
2. Finally:
- Definition:
- The
finallyblock is used to execute important code (like cleanup) regardless of whether an exception occurs or not.
- The
- Usage:
public class FinallyExample {
public static void main(String[] args) {
try {
int result = 10 / 0; // This will throw an ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Exception caught: " + e.getMessage());
} finally {
System.out.println("Finally block is always executed.");
}
}
}
- Key Points:
- The
finallyblock is executed even if there is areturnstatement in thetryorcatchblock.
- The
3. Finalize:
- Definition:
- The
finalize()method is called by the garbage collector before an object is destroyed.
- The
- Usage:
public class FinalizeExample {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize method called");
}
public static void main(String[] args) {
FinalizeExample obj = new FinalizeExample();
obj = null; // Make the object eligible for garbage collection
System.gc(); // Request garbage collection
}
}
- Key Points:
- The
finalize()method is rarely used in modern applications. - Use
try-with-resourcesor explicit resource management instead of relying onfinalize().
- The
Comparison Table:
| Feature | Final | Finally | Finalize |
|---|---|---|---|
| Definition | Used to apply restrictions. | Ensures cleanup after exceptions. | Invoked before object destruction. |
| Applies To | Variables, methods, and classes. | try-catch-finally blocks. | Objects eligible for garbage collection. |
| Purpose | Prevent modification/overriding. | Guarantee code execution. | Cleanup before object removal. |
| When Used | During design/declaration. | During exception handling. | Automatically by JVM. |
Try-With-Resources in Java
The try-with-resources statement in Java is a powerful feature introduced in Java 7 that simplifies resource management by ensuring that resources are automatically closed after their usage. Resources like files, sockets, or database connections implement the AutoCloseable interface and can be used within this statement.
Syntax
try (ResourceType resource = new ResourceType()) {
// Use the resource
} catch (ExceptionType e) {
// Handle exception
} finally {
// Optional cleanup code
}
How it Works
- Resources declared inside the parentheses of the
tryblock are automatically closed at the end of the block. - The
close()method of the resource is called, ensuring proper cleanup. - This eliminates the need for a
finallyblock to close resources explicitly.
Example 1: Reading a File
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example:
- A
BufferedReaderis opened to read a file. - The
readerresource is automatically closed when thetryblock is exited, even if an exception occurs.
Example 2: Database Connection
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DatabaseExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM employees");
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
System.out.println("Employee ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example:
- Multiple resources (
Connection,PreparedStatement,ResultSet) are declared in thetry-with-resourcesstatement. - All resources are closed automatically in reverse order of their declaration.
Benefits
- Simplifies Code: Reduces boilerplate code by eliminating the need for explicit resource closure.
- Avoids Resource Leaks: Ensures that resources are properly closed, even in the presence of exceptions.
- Improves Readability: Makes the code easier to understand and maintain.
Important Notes
- Resource Scope: Resources declared in the
try-with-resourcesstatement are limited to the scope of thetryblock. - AutoCloseable Interface: Custom resources must implement the
AutoCloseableorCloseableinterface to be used with try-with-resources.
Example of a Custom Resource
class CustomResource implements AutoCloseable {
public void useResource() {
System.out.println("Using custom resource.");
}
@Override
public void close() {
System.out.println("Custom resource closed.");
}
}
public class CustomResourceExample {
public static void main(String[] args) {
try (CustomResource resource = new CustomResource()) {
resource.useResource();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
Using custom resource. Custom resource closed.