Exceptions (or exceptional events) are problems that arise during the execution of a program. When an exception occurs, the normal flow of the program is interrupted and the program/application terminates abnormally, which is very user-unfriendly. Therefore, handle these exceptions reasonably.
Exceptions can occur for many different reasons, the following are some of the situations in which exceptions can occur.
Some exceptions are caused by user error, and some exceptions are caused by programmer error, or by some kind of physical resource.
Based on there are three types of exceptions, you need to understand them to understand how exception handling works in Java.
Sample code -
import java.io.File;
import java.io.FileReader;
public class FilenotFoundDemo {
public static void main(String args[]) {
File file = new File("D://file.txt");
FileReader fr = new FileReader(file);
}
}
If the above program is compiled, the following exception occurs.
C:\>javac FilenotFoundDemo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
FileReader fr = new FileReader(file);
^
1 error
Note - Since the
FileReader
classread()
andclose()
method throwIOException
, you can see that the compiler notices that both exceptions are required to be handledIOException
as along withFileNotFoundException
Unchecked Exceptions − Unchecked exceptions are exceptions that occur at execution time. These are also called runtime exceptions. These include programming errors, such as logic errors or improper use of APIs, runtime exceptions ignored by compile time.
For example, if you declare an array of size 5 in your program, but you try to call the 6th element of the array then an ArrayIndexOutOfBoundsExceptionexception occurs.
public class UncheckedDemo {
public static void main(String args[]) {
int num[] = {1, 2, 3, 4};
System.out.println(num[5]);
}
}
If the above program is compiled and executed, the following exception occurs.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Exceptions.UncheckedDemo.main(UncheckedDemo.java:8)
Error - This is not strictly an exception, it is a problem beyond the control of the user or programmer. Errors are usually ignored in code because rarely anything is done about them. For example, if a stack overflow occurs, there will be an error. They are also ignored at compile time.
All exception classes are subtypes of java.lang.Exception
class. The Exception
class is a subclass of a Throwable
class. In addition to the Exception
class, there is another subclass named Error
, which is derived from the Throwable
class.
Errors are exceptional conditions that occur in case of critical failures, and Java programs do not handle these conditions.
Example: JVM is out of memory. Normally, programs cannot recover from errors.
The Exception class has two main subclasses: IOException class and RuntimeException Class
![]() |
Following is a list of the most common checked and unchecked Java built-in exception classes .
Following is the list of methods available in the Throwable
class.
Numbering | method | abnormal |
---|---|---|
1 | public String getMessage() |
Returns a detailed message about the exception that occurred Throwable , initialized in the constructor. |
2 | public Throwable getCause() |
Returns the reason for the exception represented by the Throwable object. |
3 | public String toString() |
Returns the class name connected with the getMessage() result. |
4 | public void printStackTrace() |
Prints the result of toString() along with the stack trace to System.err, the error output stream |
5 | public StackTraceElement [] getStackTrace() |
Returns an array containing each element on the stack trace. The element at index 0 represents the top of the call stack, while the last element in the array represents the method at the bottom of the call stack. |
6 | public Throwable fillInStackTrace() |
Populates this Throwable object's stack trace with the current stack trace, adding any previous information from the stack trace. |
Exceptions can be caught using a combination of the try
and catch
keywords in a method. try/catch
Blocks are placed around code that may generate exceptions. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following
grammar
try {
// Protected code
} catch (ExceptionName e1) {
// Catch block
}
Put exception-prone code in try
blocks. When an exception occurs, the exception is catch
handled by the block associated with it. Each try
block should be immediately followed by a catch
block or blocks finally
.
catch
statement involves declaring the type of exception that is attempted to catch. If an exception occurs in the protected code, the try
following catch
block (or blocks) are checked. If the type of exception that occurred is listed in the catch
block, the exception is passed to the catch
block just like a parameter is passed to a method parameter.
example
The following is 2
an array declared with elements, then attempting to access the element of the array throws an exception 3
.
// ExcepTest.java
import java.io.*;
public class ExcepTest {
public static void main(String args[]) {
try {
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
Execute the above sample code and get the following results:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
A try
block can be followed by multiple catch
blocks, the syntax of multiple catch
blocks is as follows −
grammar
try {
// Protected code
} catch (ExceptionType1 e1) {
// Catch block
} catch (ExceptionType2 e2) {
// Catch block
} catch (ExceptionType3 e3) {
// Catch block
}
Three blocks are placed in the catch
statement above , but any number of blocks can be obtained in a single attempt. If an exception occurs in the protected code, the exception will be thrown to the first catch
If the data type of the exception thrown matches ExceptionType1, it gets caught there. If not, the exception is passed to the second catch
statement. This continues until the exception is caught, in which case the current method stops executing and the exception is thrown to the previous method on the call stack.
try/catch
Following is the code snippet showing how to use multiple statements.
try {
file = new FileInputStream(fileName);
x = (byte) file.read();
} catch (IOException i) {
i.printStackTrace();
return -1;
} catch (FileNotFoundException f) // Not valid! {
f.printStackTrace();
return -1;
}
Catching Multiple Types of Exceptions
Since Java 7, it is possible to use a single catch
block to handle multiple exceptions, this feature simplifies the code. Below is an application example −
catch (IOException|FileNotFoundException ex) {
logger.log(ex);
throw ex;
If a method does not handle checked exceptions, the method must declare it using throws
the keyword. The keyword should be placed at the end of the method signature.
An exception can be thrown using the throw
keyword, either a newly instantiated exception or a freshly caught exception.
The difference between the throws
and throw
keywords is for deferring handling of checked exceptions and throw
for calling exceptions explicitly.
The following method declares that it throws RemoteException
-
import java.io.*;
public class className {
public void deposit(double amount) throws RemoteException {
// Method implementation
throw new RemoteException();
}
// Remainder of class definition
}
A method can be declared to throw multiple exceptions, in which case the exceptions are declared in a comma-separated list. For example, the following method declares that it throws RemoteException
and InsufficientFundsException
exception −
import java.io.*;
public class className {
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException {
// Method implementation
}
// Remainder of class definition
}
finally
block after try
block or catch
blocks. Regardless of whether an exception occurs in the protected code block, the code in the block will eventually be executed finally
.
Use a finally
block to run any sanitization-type statements to be executed regardless of what is happening in the protected code.
finally
Blocks are placed at catch
the end of the block and its syntax syntax is as follows −
try {
// Protected code
} catch (ExceptionType1 e1) {
// Catch block
} catch (ExceptionType2 e2) {
// Catch block
} catch (ExceptionType3 e3) {
// Catch block
}finally {
// The finally block always executes.
}
Example
public class ExcepTest {
public static void main(String args[]) {
int a[] = new int[2];
try {
System.out.println("Access element three :" + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}finally {
a[0] = 6;
System.out.println("First element value: " + a[0]);
System.out.println("The finally statement is executed");
}
}
}
Execute the above sample code and get the following result −
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 First element value: 6 The finally statement is executed
When using finally
, you need to pay attention to the following rules -
A catch clause cannot exist without a try statement.
It is not compulsory to have finally clauses whenever a try/catch block is present.
The try block cannot be present without either catch clause or finally clause.
Any code cannot be present in between the try, catch, finally blocks.
In general, when using any resources like streams, connections, etc., you want to close them explicitly using finally
blocks. In the following program, we are reading data from a file using FileReader and we are closing it using finally block
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadData_Demo {
public static void main(String args[]) {
FileReader fr = null;
try {
File file = new File("file.txt");
fr = new FileReader(file); char [] a = new char[50];
fr.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); // prints the characters one by one
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
try-with-resources
, also known as automatic resource management, is a new exception handling mechanism introduced in Java 7 that automatically closes resources used in try/catch
blocks.
To use this statement, simply declare the desired resource within parentheses, and the created resource will be automatically closed at the end of the block. Following is the syntax of the try-with-resources
statement.
grammar
try(FileReader fr = new FileReader("file path")) {
// use the resource
} catch () {
// body of catch
}
}
Following is the program to read data from a file using try-with-resources
statement.
import java.io.FileReader;
import java.io.IOException;
public class Try_withDemo {
public static void main(String args[]) {
try(FileReader fr = new FileReader("E://file.txt")) {
char [] a = new char[50];
fr.read(a); // reads the contentto the array
for(char c : a)
System.out.print(c); // prints the characters one by one
} catch (IOException e) {
e.printStackTrace();
}
}
}
When using try-with-resources
statements, keep the following points in mind.
To use a class with try-with-resources statement it should implement AutoCloseable interface and the close() method of it gets invoked automatically at runtime.
You can declare more than one class in try-with-resources statement.
While you declare multiple classes in the try block of try-with-resources statement these classes are closed in reverse order.
Except the declaration of resources within the parenthesis everything is the same as normal try/catch block of a try block.
The resource declared in try gets instantiated just before the start of the try-block.
The resource declared at the try block is implicitly declared as final
You can create your own exceptions in Java. While writing your own exception classes, please note the following points −
Throwable
.Exception
class.RuntimeException
class.You can define your own Exception
class as follows −
class MyException extends Exception {
}
You just need to extend the predefined Exception
classes to create your own Exception
. These are checked exceptions. The following InsufficientFundsException
class is a user-defined exception that extends the Exception
class to make it a checked exception. Exception classes are like any other class, containing useful fields and methods.
example
//InsufficientFundsException.java
import java.io.*;
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
To demonstrate how to use user-defined exceptions, the following CheckingAccount class contains a withdraw() method that throws an InsufficientFundsException
// CheckingAccount.java
import java.io.*;
public class CheckingAccount {
private double balance;
private int number;
public CheckingAccount(int number) {
this.number = number;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) throws InsufficientFundsException {
if(amount <= balance) {
balance -= amount;
}else {
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
public double getBalance() {
return balance;
}
public int getNumber() {
return number;
}
}
The following BankDemo
program demonstrates how to call the deposit() and withdraw() methods of CheckingAccount.
// BankDemo.java
public class BankDemo {
public static void main(String [] args) {
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try {
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
} catch (InsufficientFundsException e) {
System.out.println("Sorry, but you are short $" + e.getAmount());
e.printStackTrace();
}
}
}
Execute the above sample code and get the following result −
Depositing $500...
Withdrawing $100...
Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
at CheckingAccount.withdraw(CheckingAccount.java:25)
at BankDemo.main(BankDemo.java:13)
Common exception
In Java, two categories can be defined: exceptions and errors.
NullPointerException
, ArrayIndexOutOfBoundsException
, ClassCastException
.IllegalArgumentException
, IllegalStateException