Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify/reuse this exception handling code

I tend to write code like the following a lot:

BufferedWriter w = null; // Or any other object that throws exceptions and needs to be closed
try {
    w = new BufferedWriter(new FileWriter(file));
    // Do something with w
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (w != null) {
        try {
            w.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

It usually involves an object that throws exceptions and needs to be closed, and that closing it may also throw an exception.

I was wondering if the above code can be simplified or reused in any way.

like image 330
hpique Avatar asked Oct 11 '10 14:10

hpique


People also ask

What are the 2 ways I can handle exception?

Java provides two different options to handle an exception. You can either use the try-catch-finally approach to handle all kinds of exceptions. Or you can use the try-with-resource approach which allows an easier cleanup process for resources.

How do you handle exception handling?

The try-catch is the simplest method of handling exceptions. Put the code you want to run in the try block, and any Java exceptions that the code throws are caught by one or more catch blocks. This method will catch any type of Java exceptions that get thrown. This is the simplest mechanism for handling exceptions.

Can you Rethrow an exception?

If a catch block cannot handle the particular exception it has caught, you can rethrow the exception. The rethrow expression ( throw without assignment_expression) causes the originally thrown object to be rethrown.


2 Answers

If you don't want to write code for closing in finally block, you should have a look at Project Lombok

Instead of writing the normal

public class CleanupExample {
  public static void main(String[] args) throws IOException {
  InputStream in = new FileInputStream(args[0]);
  try {
    OutputStream out = new FileOutputStream(args[1]);
    try {
      byte[] b = new byte[10000];
      while (true) {
         int r = in.read(b);
         if (r == -1) break;
         out.write(b, 0, r);
      }
    } finally {
        out.close();
      }
  } finally {
     in.close();
    }
  }
}

With Lombok you can write

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
   }
 }

Much more readable, and it generates the correct way of closing the Stream. This works with all the Closeable interfaces

like image 151
Shervin Asgari Avatar answered Sep 28 '22 16:09

Shervin Asgari


I usually put contents of your finally block in a helper. Like this

void close(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException e) {
            // perform logging or just ignore error
        }
    }
}

Closeable interface is implemented by many classes (input streams, database connections, etc), so this is kinda general-purpose helper.

like image 35
Nikita Rybak Avatar answered Sep 28 '22 17:09

Nikita Rybak