background

In daily development, resources such as I/O streams, database connections, and so on are often closed manually. Leaving it on can have serious performance consequences.

Problems with try-finally

1. Code is not elegant

Closing IO streams manually, especially when multiple IO streams are used, can be extremely unwieldy. Here’s an example:

public static void main(String[] args) { BufferedInputStream inputStream = null; BufferedOutputStream outputStream = null; try { inputStream = new BufferedInputStream(new FileInputStream("t1.txt")); outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt")); } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); }}}}Copy the code

Nested writes are often used to ensure that both inputStream and outputStream are closed properly.

If finally is written like this:

public static void main(String[] args) { BufferedInputStream inputStream = null; BufferedOutputStream outputStream = null; try { inputStream = new BufferedInputStream(new FileInputStream("t1.txt")); outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt")); } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); }}}Copy the code

When the inputStream. Close (); If an exception occurs, outputstream.close () will no longer be run; It will never be able to release resources.

2. Abnormal shielding

Throws only one exception when we wish to throw an exception to upper throws. In the following example, the exception of inputStream is masked by outStream.

The console displays only outStream exceptions:

Use the try – with – the resource

Java 7 introduced try-with-Resources to help us quickly resolve resource release.

Using try-with-resource is much more elegant.

public static void main(String[] args) { try ( BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("t1.txt")); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt")); ) { } catch (Exception e) { e.printStackTrace(); }}Copy the code

A try-with-resource is a resource that automatically completes a close for us. The following is a compiled class that is similar to the try-finally class.

public static void main(String[] args) { try { BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("t1.txt")); try { BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt")); outputStream.close(); } catch (Throwable var5) { try { inputStream.close(); } catch (Throwable var4) { var5.addSuppressed(var4); } throw var5; } inputStream.close(); } catch (Exception var6) { var6.printStackTrace(); }}Copy the code