Exceptions

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 5

Exceptions

Exception Hierarchy in Java

In the java exception class hierarchy, the class at the top is the Throwable class, which is a direct
subclass of the Object class. Throwable has two direct subclasses Exception and Error, which has again
respective sub-classes The diagram below shows the standard exception and error classes defined in
Java, organized in the Java exceptions hierarchy.

Errors

 Error caused by the lack of system resources such as heap memory is not available etc. Errors are
non-recoverable. During the runtime of a program if any error occurs we will not be able to handle
it.
 Error is a subclass of Throwable that indicates serious problems that a reasonable application
should not try to catch.
 Handling specific errors:

Java Errors such as OutOfMemoryError, StackOverflowError, etc., are typically caused by problems with
the JVM or system resources. While you cannot recover from such errors in most cases, you can handle
them or mitigate their effects by:

o Increasing system resources (e.g., heap space for OutOfMemoryError).


o Avoiding recursive calls (to prevent StackOverflowError).
o Optimizing memory management (such as using better data structures and algorithms)
Exceptions

In Java, exceptions are divided into two types: checked exceptions and unchecked exceptions.

 Checked exceptions
 Unchecked exceptions

Checked Exceptions

 Checked exceptions are exceptions that must be either caught or declared in the
method’s throws clause. They extend the Exceptionclass but do not extend RuntimeException.
The Java compiler requires that checked exceptions are explicitly handled (caught) within a try-
catch block or declared to be thrown by the method using the throws keyword.
 Common examples are IOException, SQLException, and ClassNotFoundException.
 Checked exceptions are generally recoverable.
 Handling: Because these exceptions are checked at compile time, developers must handle them,
which can result in more robust code. If a checked exception is not handled properly, the code
will fail to compile.
 Use Case: Checked exceptions are commonly used for recoverable conditions in which the caller
can reasonably expect to handle the exception.

Unchecked exceptions

 Unchecked exceptions are those that are not checked during compile-time. They derive from
the RuntimeException class and can occur at any time during program execution.
 Common examples are NullPointerException, ArrayIndexOutOfBoundsException, and
IllegalArgumentException.
 Handling: Developers are not required to handle unchecked exceptions, so they can either catch
them or let them propagate up the call stack. This can result in simpler code, but it can also
cause runtime errors if not managed properly.
 Unchecked exceptions are commonly used for programming errors, such as logic errors or
improper API usage, from which the caller cannot reasonably be expected to recover.

Checked Exceptions Unchecked Exceptions


Checked exceptions are those that are checked at It can occur at any time during program
compile time. execution or during runtime.
Subclass of Exception but not RuntimeException Subclass of RuntimeException
Must be either caught using try-catch block or We can’t handle using try-catch
declared in the method signature using throws
Used for recoverable errors (e.g., I/O issues, Used for programming errors (e.g.,
database errors) logical flaws, invalid arguments)
IOException, SQLException, ClassNotFoundException, NullPointerException, ArithmeticException,
ParseException, NoSuchMethodException, ArrayIndexOutOfBoundsException,
FileNotFoundException ClassCastException, IllegalArugementException
How to handle exceptions in Java?

In Java, exceptions are handled using a combination of try, catch, throw, throws, and finally blocks.

throw Vs throws

throw keyword:

 Used to explicitly throw an exception within a method.


 When an exception is thrown using throw, the program control is immediately transferred to the
nearest catch block, or if no catch block is present, the program terminates with the exception.
 You can throw both built-in and custom exceptions with throw.

public class ThrowExample {


public static void main(String[] args) {
try {
checkAge(15); // This will throw an exception
} catch (IllegalArgumentException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
public static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be at least 18");
}
}
}
throws keyword:

 Used in method signatures to declare that a method might throw one or more exceptions, which
must be handled by the caller of the method.

public class ThrowsExample {


public static void main(String[] args) {
try {
readFile();
} catch (IOException e) {
System.out.println("Caught IOException: " + e.getMessage());
}
}
public static void readFile() throws IOException {
FileReader file = new FileReader("nonexistentfile.txt");
BufferedReader fileInput = new BufferedReader(file);
System.out.println(fileInput.readLine());
fileInput.close();
}
}
Best Practices for Exception Handling

1. Catch Specific Exceptions: Always catch the most specific exception first and then more general
exceptions later. This allows you to handle different errors differently.
2. Use finally for Cleanup: Always use finally to clean up resources (like closing files, database
connections, etc.) to avoid resource leaks.
3. Don’t Use Exceptions for Control Flow: Exceptions should not be used for normal control flow (e.g.,
using exceptions to exit a loop). They are intended for exceptional conditions that you want to
handle explicitly.
4. Log Exceptions: Log exceptions to help debug issues in production. This can be done using logging
frameworks like SLF4J, Log4j, or Java's built-in logging.
5. Handle Exceptions at the Right Level: Handle exceptions at the appropriate level in your application.
Don’t catch exceptions too early in the program; let them propagate up if they can’t be handled
effectively at the current level.
6. Provide Useful Messages: When throwing or catching exceptions, provide meaningful error
messages that can help diagnose the problem.

try-with-resources

 In Java, the finally block is a critical part of exception handling, designed to ensure that a block of
code runs regardless of whether an exception occurs. The typical use case for a finally block is to
release resources, close connections, or clean up after a try block, which may throw an exception.
However, there are some scenarios where the finally block might not execute.
 While the finally block is intended to always run, there are a few specific circumstances where it
might not:
o JVM Termination
o Power Failure or Hardware Crash
o Infinite Loops or Blocking Calls
 To ensure resources are always released properly, especially when dealing with I/O operations, Java 7
introduced the try-with-resources statement. This feature ensures that each resource is closed at the
end of the statement, regardless of whether an exception is thrown.

try (FileInputStream file = new FileInputStream("file.txt")) {


// use the file
} catch (IOException e) {
e.printStackTrace();
} // file is automatically closed here

In this example, the FileInputStream is automatically closed at the end of the try block, ensuring
proper resource cleanup without the need for an explicit finally block.
finally()
The finally block is part of exception handling and is used to define a block of code that will be executed
after a try block, regardless of whether an exception was thrown or not. The finally block is typically
used to release resources, such as closing files, closing database connections, or releasing network
resources, that were acquired during the execution of the try block.

Key Points about finally in Java:

 Guaranteed Execution: The finally block always executes after the try block finishes, whether an
exception is thrown or not.
 Even with a Return Statement: If a return statement is encountered in the try block,
the finally block will still execute before the method returns.
 Execution After Exception: If an exception is thrown in the try block and caught by a catch block,
the finally block will still execute after the catch block.
 Exception Handling with finally: If an exception occurs inside the finally block, it will propagate, but
the code after the finally block may not execute.
 The finally block can exist with or without a catch block, but it must be preceded by a try block.

Can we have finally () without try ()?

No, you cannot have a finally block without a try block in Java. The finally block is always associated with
a try block (and optionally a catch block) in Java's exception handling mechanism. The purpose of
the finally block is to ensure that certain cleanup actions (like closing resources) are always performed,
regardless of whether an exception is thrown or caught.

Since finally is part of the exception handling mechanism, it must be tied to a try block. Without
a try block, the concept of "exception handling" doesn’t apply, and thus the finally block is not required.

You might also like