Java, please give priority to use try-with-resources rather than try-finally

img

Java, please give priority to use try-with-resources rather than try-finally

Java library contains a lot of manual need to call the close method to close the resource. For example, InputStream, OutputStream, and java.sql.Connection. Close the resource often overlooked by the client, which can lead to terrible performance problems. Although many resources to use as a safety net terminator, terminator but it is not so satisfactory.

From an historical perspective, try-finally statement is the best way to ensure resources are properly closed, it is also the case even in the face of an exception or return statement:

// try-finally - No longer the best way to close resources!

static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try {

      return br.readLine();

    } finally {

      br.close();

    }

}

It looks pretty good, but when you add a second resource when the situation becomes a little bit worse:

// try-finally is ugly when used with more than one resource!

  static void copy(String src, String dst) throws IOException {

    InputStream in = new FileInputStream(src);

    try {

      OutputStream out = new FileOutputStream(dst);

      try {

        byte[] buf = new byte[BUFFER_SIZE];

        int n;

        while ((n = in.read(buf)) >= 0)

          out.write(buf, 0, n);

      } finally {

        out.close();

      }

    } finally {

      in.close();

} 

}

Although hard to believe, but even good programmers will often write code like this. For starters, I pointed out the problems in Java Puzzlers [Bloch05] on page 88, but for years no one noticed. In fact, in 2007, two-thirds in the Java library is wrong to use the close method.

Even using the try-finally statement closes the proper code resource (e.g., the previous two code example), there are some minor problems. try block and finally block code can throw an exception. For example, in firstLineOfFile method, since the failure of the underlying physical devices, call the readLine might throw an exception, call the close will fail for the same reason. In these cases, the second exception would completely hide out first. The first record is not an exception in the exception stack of information, which will greatly increase the complexity of the commissioning of the real system - Generally speaking, the key issue is the first abnormality diagnosis. While it is possible to suppress the second exception by writing code, preserving the first exception information, but no one would do that, because too much trouble.

All of these issues with the introduction of Java 7 try-with-resources statement has been resolved [JLS, 14.20.3] . To use this structure, the resources necessary to implement AutoCloseable interface, which contains the only close void return type of a method. Many libraries Java classes and interfaces with third-party libraries are now achieved or inherited AutoCloseable. If you write a class used to represent resource, it must be closed, then this class should implement AutoCloseable.

Using the following code try-with-resources rewrite the first example above:

// try-with-resources - the the best way to close resources!

  static String firstLineOfFile(String path) throws IOException {

    try (BufferedReader br = new BufferedReader(

        new FileReader(path))) {

      return br.readLine();

}

}

Using the following code try-with-resources rewriting the second example above:

// try-with-resources on multiple resources - short and sweet

  static void copy(String src, String dst) throws IOException {

    try (InputStream  in = new FileInputStream(src);

 OutputStream out = new FileOutputStream(dst)) {

byte[] buf = new byte[BUFFER_SIZE];

int n;

while ((n = in.read(buf)) >= 0)

  out.write(buf, 0, n);

  } 

}

try-with-resources version only code more concise and readable than the original better, but also provides the ability to better diagnose the problem. Consider firstLineOfFile method. If you call the readLine (not visible) close methods throw an exception, then the latter exception will be the former suppressed. In fact, multiple exceptions will be suppressed, thus preserving the anomaly you actually want to see. These abnormalities are not pressed is discarded; they will be printed in the stack, and a corresponding symbol that they are suppressed. You can also access these exceptions programmatically by getSuppressed method, which is to be added to the Throwable in Java 7's.

You can catch clause put on the try-with-resources statement, just like regular try-finally statement. This will and will not disturb the code on another nesting level while processing exception. For example, the following is not an exception thrown firstLineOfFile version of the method, but if you can not open the file or can not read the file, then it receives a default value to return:

// try-with-resources with a catch clause

  static String firstLineOfFile(String path, String defaultVal) {

    try (BufferedReader br = new BufferedReader(

        new FileReader(path))) {

      return br.readLine();

    } catch (IOException e) {

      return defaultVal;

} 

}

Obviously, when dealing with resources need to be closed, please give priority to use the try-with-resources rather than try-finally. The results of the code shorter and clearer, more useful abnormal also it generates. try-with-resources statement makes writing code must be used to turn off resources more easily, and this is the try-finally can not.


Upon inquiry Source: InputStream / BufferReader, these classes have been achieved to realize the AutoClosed class.

Big baby summary:

Use this syntax as much as possible, to write your own program yesterday there are still two try finally statement today to experience the convenience.

try-with-resource syntax:

the try (resource resource definition to be closed here) {

Related operations write here

}

Guess you like

Origin www.cnblogs.com/bigbaby/p/12556613.html
Recommended