Java7 try-with-resources Statement advantage

夙愿已清 提交于 2019-11-26 05:28:09

问题


I was looking the new feature of Java7. I found one is try-with-resources Statement. Can anybody tell me what exactly it means? Why and where we should use it and where we can get advantage of this feature? Even the try statement misses catch block which confusing for me.


回答1:


It was introduced because of some resources used in Java (like SQL connections or streams) being difficult to be handled properly; as an example, in java 6 to handle a InputStream properly you had to do something like:

InputStream stream = new MyInputStream(...);
try {
    // ... use stream
} catch(IOException e) {
   // handle exception
} finally {
    try {
        if(stream != null) {
            stream.close();
        }
    } catch(IOException e) {
        // handle yet another possible exception
    }
}

Do you notice that ugly double try? now with try-with-resources you can do this:

try (InputStream stream = new MyInputStream(...)){
    // ... use stream
} catch(IOException e) {
   // handle exception
}

and close() is automatically called, if it throws an IOException, it will be supressed (as specified in the Java Language Specification 14.20.3) . Same happens for java.sql.Connection




回答2:


As stated in the documentation:

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly

You can read more from here.




回答3:


In Java, if you use a resource like input or output streams you always have to close it after using. It also can throw exceptions so it has to be in a try catch block. The closing has to be in the finally block. This is a least the way until Java 7. This has several disadvantages:

  • You'd have to check if your ressource is null before closing it
  • The closing itself can throw exceptions so your finally had to contain another try - catch
  • Programmers tend to forget to close their ressources

While the first two are mostly syntax issues, the last one is more critical. So if you use the try-with statement your code gets a lot cleaner and most importantly: Your ressource will always be closed :-)




回答4:


The advantage is you need not explicitly close the resources you have defined in try-with-resources Statement. JVM will take care of it. It will automatically close those resources for you.

Generally problems developers face is to structure the try-catch-finally blocks because even in finally block where we close the resources we have to use try-catch. There are various structures of try-catch-finally statement to help resolve this issue but try-with-resources Statement will basically help you ease your coding structure logic.




回答5:


Update from 2017 after Java 9 release

Now with Java 9 we have more syntactic sugar and we can have a resource declared outside the try-catch block but still handled properly.

Let's take for example this Java 6 way of handling the resource:

InputStream stream = new MyInputStream(...);
try {
    // ... use stream
} catch(IOException e) {
   // handle exception
} finally {
    try {
        if(stream != null) {
            stream.close();
        }
    } catch(IOException e) {
        // handle yet another possible exception
    }
}

Here we can notice that this code is incredibly ugly as pointed out in other answers.

So the solution in Java 7 was to introduce this try-catch-with-resource:

try (InputStream stream = new MyInputStream(...)){
    // ... use stream
} catch(IOException e) {
   // handle exception
}

This notation is surely way better than the previous one, however we have a problem. If the resource (strem in this case) has been declared previously but we want to be sure that it's handled correctly in this block we need a trick like this:

InputStream stream = new MyInputStream(...)
try (InputStream stream2 = stream) {
   // do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
   // handle exception
}

We can notice that this situation can be addressed only with another piece of ugly code. That's why with Java 9 the Try-With-Resources has been improved introducing a new syntax:

InputStream stream = new MyInputStream(...)
try (stream) {
   // do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
   // handle exception
}

Note that this syntax will result in a compile time error for Java version 8 or minor

This is more "natural" way of writing even though in most use cases we don't need the resource outside the scope of the try block. The only restriction is that the reader variable should be effectively final or just final.




回答6:


Benefits of Using Try with Resources

  1. More readable code and easy to write.

  2. Automatic resource management.

  3. Number of lines of code is reduced.

  4. No need of finally block just to close the resources.

  5. We can open multiple resources in try-with-resources statement separated by a semicolon. For example, we can write following code.

  6. When multiple resources are opened in try-with-resources, it closes them in the reverse order to avoid any dependency issue. You can extend my resource program to prove that.

public void sampleTryWithResource() {
            try(Connection dbCon = DriverManager.getConnection("url", "user", "password");
                    BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));) {
                //...Your Business logic
            } catch (Exception e) {
                //...Exception Handling
            }
        }



回答7:


What about this - if resource is initialized inside try{} is'nt it automatically closed ?

try {
            Scanner scanner = new Scanner(new File(csvFile));
            while (scanner.hasNext()) {
                 // do something
            }
            scanner.close();
        }catch(FileNotFoundException fnfe)
        {
            System.err.println(fnfe.getLocalizedMessage());
        }


来源:https://stackoverflow.com/questions/17739362/java7-try-with-resources-statement-advantage

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!