Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the reason why the third edition of effective java recommends try-with-resources instead of try-finally

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "what is the reason why the third edition of effective java recommends using try-with-resources instead of try-finally", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what is the reason why the third edition of effective java recommends using try-with-resources instead of try-finally?"

Background

The sentence try-finally must be no stranger to students who do java. Whenever we need to close resources, we will use the sentence try-finally. For example, when we use locks, both local reentrant locks and distributed locks will have the following similar structural code. We will unlock in finally to force unlocking:

Lock lock = new ReentrantLock (); lock.lock (); try {/ / doSometing} finally {lock.unlock ();}

Or when we use java's file stream to read or write files, we will also forcibly close the file stream in finally to prevent resource leakage.

InputStream inputStream = new FileInputStream ("file"); try {System.out.println (inputStream.read (new byte [4]));} finally {inputStream.close ();}

In fact, at first glance, there should be no problem with this way of writing, but what should we do if we have multiple resources that need to be closed? The most common way to write is as follows:

InputStream inputStream = new FileInputStream ("file"); OutputStream outStream = new FileOutputStream ("file1"); try {System.out.println (inputStream.read (new byte [4])); outStream.write (new byte [4]);} finally {inputStream.close (); outStream.close ();}

We define two resources outside, and then close these two resources one by one in finally. This is how some teaching articles were taught when I first wrote java to close file streams and database connection pools, so what's wrong with this? The problem is that if an exception is thrown during inputStream.close, outStream.close () will not be executed, which is obviously not what we want, so it will be written in the following multi-nested way:

InputStream inputStream = new FileInputStream ("file"); try {System.out.println (inputStream.read (new byte [4])); try {OutputStream outStream = new FileOutputStream ("file1"); outStream.write (new byte [4]);} finally {outStream.close ();}} finally {inputStream.close ();}

In this way, even if outStream.close () throws an exception, we still execute inputStream.close () because they are in different finally blocks, which does solve our problem, but there are two problems that remain unsolved:

The first question is, if we have more than two resources, say ten resources, do we need to write ten nested statements? Can you still read this code after writing it?

The second problem is that if we have an exception in try and then an exception in finally, it will cause the exception to be overwritten, which will cause the exception in finally to overwrite the exception in try.

Public class CloseTest {public void close () {throw new RuntimeException ("close");} public static void main (String [] args) {CloseTest closeTest = new CloseTest (); try {throw new RuntimeException ("doSomething");} finally {closeTest.close ();}} output result: Exception in thread "main" java.lang.RuntimeException: close

In the above code, we expect to be able to throw this exception of doSomething, but the actual data result is the exception of close, which is not in line with our expectations.

Try-with-resources

We introduced two problems above, so we introduced the try-with-resources statement in java7. As long as our resources implement the AutoCloseable interface, we can use this statement. Our previous file stream has already implemented this interface, so we can directly use:

Try (InputStream inputStream = new FileInputStream ("file"); OutputStream outStream = new FileOutputStream ("file1")) {System.out.println (inputStream.read (new byte [4])); outStream.write (new byte [4]);}

All of our resource definitions are defined in parentheses after try, and in this way we can solve several of the problems mentioned above:

First of all, the first question, in this way, the code is very clean, no matter how many resources you have, you can do it very succinctly.

For the second exception coverage problem, we can take a look at it through an experiment, and we rewrite the code as follows:

Public class CloseTest implements AutoCloseable {@ Override public void close () {System.out.println ("close"); throw new RuntimeException ("close");} public static void main (String [] args) {try (CloseTest closeTest = new CloseTest (); CloseTest closeTest1 = new CloseTest ();) {throw new RuntimeException ("Something") The output result is: closecloseException in thread "main" java.lang.RuntimeException: Something at fudao.CloseTest.main (CloseTest.java:33) Suppressed: java.lang.RuntimeException: close at fudao.CloseTest.close (CloseTest.java:26) at fudao.CloseTest.main (CloseTest.java:34) Suppressed: java.lang.RuntimeException: close at fudao .CloseTest.close (CloseTest.java:26) at fudao.CloseTest.main (CloseTest.java:34)

We define two CloseTest in the code to verify whether the previous close exception will affect the second one. At the same time, different exceptions are thrown in both close and try blocks. You can see our results and output two close, proving that although close throws an exception, both close will be executed. Then output the exception of doSomething, we can find that what we output here is the exception thrown in our try block, and the exception of our close is recorded in the stack of exceptions in the way of Suppressed, in this way we can record both kinds of exceptions.

Try-with-resources principle

The try-with-resources statement is actually a syntactic candy that compiles and returns to the nested mode we started talking about:

You can find that after try-with-resources is compiled, it adopts the nested mode, but it is a little different from the previous nesting. When he close, he uses catch to catch the exception, and then add it to our real exception. The overall logic is a little more complex than our previous nesting.

At this point, I believe you have a deeper understanding of "what is the reason why the third edition of effective java recommends using try-with-resources instead of try-finally?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report