Javarevisited
Published in

Javarevisited

Exception Handling in Java

Exception is an unwanted event which occurs while running the code.

Below is the class hierarchy in Java :

The basic idea is : try will have the business logic which may throw an error. catch block has the code to handle and catch exceptions. finally block is used for cleaning up purposes like closing a stream, closing a file, deleting a file.

try catch blocks :

The below code gives an error during compile time itself. The reason for that is createFile() is a method of java.io.File package, which internally throws an exception.

public class DemoException {
static DemoException demoException;

public static void main(String args[]) throws IOException {
demoException = new DemoException();
demoException.createFile();
}
void createFile() {
File myFile = null;
myFile = new File("newFile.txt");
System.out.println(myFile.getAbsolutePath());
if (myFile.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
}
}

There are two ways to fix the compile time issue :

1. Add throws IOException in method definition line

void createFile() throws IOException {
File myFile = null;
myFile = new File("newFile.txt");
System.out.println(myFile.getAbsolutePath());
if (myFile.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
}

2. Use a try catch block

void createFile() {
try {
File myFile = null;
myFile = new File("newFile.txt");
System.out.println(myFile.getAbsolutePath());
if (myFile.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
} catch (Exception e) {
System.out.println("An exception was thrown" + e);
}
}

So when you call any method, and it throws an error, you will have to catch the exception either in method definition or with a try catch block.

An example below :

The below code will again give a compiler exception because fileOperations method doesn’t handle the exception thrown by createFile().

public class DemoException {

public static void main(String args[]) {
fileOperations();
}
static void fileOperations() {
// compile time issue as exception is not handled
File file = createFile();

}
static File createFile() throws IOException {
File myFile = null;
try {
myFile = new File("newFile.txt");
System.out.println(myFile.getAbsolutePath());
if (myFile.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
} catch(Exception e) {
System.out.println("An exception catched :" +e);
throw new IOException();
}
return myFile;
}
}

The right solution would be to use a try catch or throws Exception in method definition like below :

static void fileOperations() {
try {
File file = createFile();
} catch (Exception e) {

}
}

or

static void fileOperations() throws IOException{
File file = createFile();
}

try with resources :

Basically try with resources is used to remove the complexity of having an extra finally block to close the files or streams. It is assured by JVM that the resources will be closed once try block execution is done.

Format of a try catch finally :

public class DemoException {

public static void main(String args[]) {
method();
}
static void method() {
try{
// open a file
// open a file stream
} catch(Exception e) {

} finally {
//close the file and the file stream
}

}
}

If we had to do the same thing using try with resources, then we will not use finally because once the try block is done executing, by default JVM will close the streams and files which were used by try.

Format of try with resources :

public class DemoException {

public static void main(String args[]) {
method();
}
static void method() {
try(){
// business logic
} catch(Exception e) {

}

}
}

Marked the code above in Bold, that is where we need to write the code to open any resources like files and streams.

An example of try with resources :


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DemoException {

static DemoException demoException;

private static final Logger LOGGER = Logger.
getLogger(Logger.GLOBAL_LOGGER_NAME);
public static void main(String args[]) throws IOException {
demoException = new DemoException();
demoException.fileOperations();
}
void fileOperations() {
try {
File file = demoException.createFile();
demoException.openOutputStream(file);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error in file");
}
}
File createFile() {
File myFile = null;
try {
myFile = new File("newFile.txt");
System.out.println(myFile.getAbsolutePath());
if (myFile.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
} catch(Exception e) {
LOGGER.log(Level.WARNING, "Error in creating file");
}
return myFile;
}
void openOutputStream(File file) throws IOException {
try (OutputStream out = new FileOutputStream(file)) {
write(out);
System.out.println("Output Stream");
}
}
void write(OutputStream out) throws IOException {
throw new IOException();
}
}
Outputs an exception. write() throws an exception. The exception is then catched by openOutputStream(). openOutputStream although doesn't have a catch block, throws an exception to fileOperations(), which is catched and then on console we see an exception logged.
Outputs : WARNING: Error in file

If you see the above code, try with resources(marked in bold) does not have a catch block, it internally takes care of catching the exception and throwing the exception to the caller of the method.

Exception handling with for loops :

What will be printed on console if you run the below code ?

public class DemoException {
public static void main(String args[]) {
for(int i = 0; i<10;i++) {
try {
throw new RuntimeException();
} catch (Exception e) {
System.out.println("Error thrown" +e);
}
}
}
}

The options are :

  1. Prints the exception just once
  2. Prints the exception 10 times

The answer is — It will print the exception 10 times, because we are handling all the exceptions inside for loop.

However, if we specifically throw an exception inside the catch block, then the Error thrown statement marked in Bold will be printed just once.

public class DemoException {
public static void main(String args[]) {
for(int i = 0; i<10;i++) {
try {
throw new RuntimeException();
} catch (Exception e) {
System.out.println("Error thrown" +e);
throw new RuntimeException();
}
}
}
}

Now, if we have try catch block outside the for loop, then also “Error thrown” is printed just once.

public class DemoException {
public static void main(String args[]) {
try {
for (int i = 0; i < 10; i++) {
throw new RuntimeException();
}
} catch (Exception e) {
System.out.println("Exception thrown" +e);
}
}
}

Conclusion :
Hope the practical examples covered all the basic scenarios we come across in our day to day activity while working on any prod application. Let me know if you think I can add any more details, or if you have any specific use case in mind ?

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store