Wechat search programmers take off can add my public number, to ensure that a dry goods update ~

This article focuses on try-with-resource grammar sugar. If you already know this grammar by heart, skip to the end of the third line :P. Ok, just kidding everyone, please follow me to understand today’s trivia

Application scenarios

If you’re a Java god, you can’t avoid using various streams or clients that need to be shut down. Such as FileInputStream, HTTPClient, etc. Then you are bound to encounter the following disgusting code

        File file = new File("/root/usr/file.txt");
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            System.out.println("fileInputStream = " + fileInputStream);
        } catch (FileNotFoundException e) {
            log.error("error", e);
        } finally {
            if (null! = fileInputStream) {try {
                    fileInputStream.close();
                } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Println (“fileInputStream = “+ fileInputStream) is used instead of a simulated business operation. Finally is a cancer for code freaks. So how do you optimize this gross, ugly piece of code? Java has already figured that out for us.

Code transformation

Try-with-resource = try-with-resource = try-with-resource

Let’s look at the effect first, then the principle. For the above large pile of code, you can change it to the following lines of general terseness. This allows programmers to focus more on business logic than exception handling and resource closing:

        File file = new File("/root/usr/file.txt");
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            System.out.println("fileInputStream = " + fileInputStream);
        } catch (IOException e) {
            log.error("error", e);
        }
Copy the code

So the reader might ask, we don’t have to worry about shutting down resources, but who does it? Virtual machines, of course! We follow the FileInputStream class and look at its parent InputStream. We see that this class implements an interface called Closeable, which in turn inherits the AutoCloseable interface from the java.lang package. This interface has only one method, which is the close method. This method is implemented in InputStream, but the body of the method is empty. The real executor is its subclass FileInputStream, which overwrites the close method to close the resource.

Some readers with friends here may have been meng, say thousand and ten thousand, inherit this to achieve that, that to the end who closed. Or rather, who does it? So please follow me into the source code moment!

Realize the principle of

Saying source code is actually a little ashamed, there is no source code to speak. It’s just that the virtual machine added finally to it at compile time. Let’s look at the decompiled class

Did someone start banging on the table and screaming that they’d been duped? Yes, there’s nothing weird about it at all, it’s just that the JVM is giving you code that you don’t want to write. As for how he is changed, you big guy please consult the JVM source code, little brother here can not help.

digression

Basically see here is true love, in fact, the above things are rotten on the Internet. So LET me just say a few more tips and interesting things about try-with-resource.

1. IDEA is automatically generated

If you are careful, you will notice that some ides (such as IDEA) already support one-click try-with-resource wrapping. For example:

2. Create your own class to implement the AutoClosable interface

In fact, the cases where we use try-with-resource syntactic sugar are not limited to shutting down various resources. You can also define your own class, as long as it implements the AutoClosable interface, wrap it with the try-with-Resource syntax, and have the JVM fill you with finally blocks. For example:

public class CustomAutoCloseImpl implements AutoCloseable{
    public void run(a) {
        // todo biz code
    }

    @Override
    public void close(a){
        System.out.println("close execute!!"); }}public class AutoCloseTest {

	public static void main(String[] args) {

		try (CustomAutoCloseImpl customAutoClose = new CustomAutoCloseImpl()) {
			customAutoClose.run();
		} catch(Exception e) { System.out.println(e.getMessage()); }}}Copy the code

This close method is definitely going to execute for you. For example, in a scenario where the person visits a web site, the number of interface calls is increased by 1 regardless of whether the business operation is successful. This increment can be placed in close and then called using try-with-resource sugar to avoid redundant code judgments. Of course, the example here may be inappropriate, but it’s just to give you an alternative way to use try-with-resource. (I’m sure there are people here who say that it defeats the purpose of the syntactic candy, but the idea is alive. There’s no need to put yourself to death.

Do try-with-resource exceptions have to be handled?

This is also a whim of mine, and you can take a look at the code below and guess what will happen

public class CustomAutoCloseImpl implements AutoCloseable{
    public void run(a) {
        throw new RuntimeException("I suppose to throw an exception!!");
    }

    @Override
    public void close(a){
        System.out.println("close execute!!"); }}public class AutoCloseTest {

	public static void main(String[] args) {

		try (CustomAutoCloseImpl customAutoClose = new CustomAutoCloseImpl()) {
			customAutoClose.run();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
        
		System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
        
		try (CustomAutoCloseImpl customAutoClose = newCustomAutoCloseImpl()) { customAutoClose.run(); }}}Copy the code

You can guess the result in your mind (in fact, you can guess right ~).

There are a couple of interesting things about looking at the results. Notice that this is a block inside a catch that executes a close method first. As for why, go to the above decompilation results you will understand. Another interesting thing is that you don’t have to use a catch for a try-with-resource. Of course, even though the close method is executed, the exception will still be thrown to you. It is also a good place to use it later, such as throwing a custom exception inside the method and throwing it outside to the global exception handler

4, try-with-resource can wrap multiple resources

Let’s just go to the code

	public static void main(String[] args) {

        try (CustomAutoCloseImpl customAutoClose = new CustomAutoCloseImpl();
             FileInputStream fileInputStream = new FileInputStream(new File(""));
             FileOutputStream fileOutputStream = new FileOutputStream(new File("")); {// todo biz code
            customAutoClose.run();
            fileInputStream.read();
            fileOutputStream.flush();
        } catch(Exception e) { System.out.println(e.getMessage()); }}Copy the code

Definition of multiple resources decompile class file is very interesting oh, you can go to the compiler to see ~

conclusion

Everything has its advantages and disadvantages. Finally, summarize the advantages and disadvantages in my opinion.

advantages

  • The biggest advantage is that you don’t have to write finally
  • Improved programmer focus on business, no need to write business code and worry about closing or not closing
  • This reduces memory leaks caused by errors such as missing or forgetting to write. After all, the virtual machine masters are reliable
  • Increased code playability

disadvantages

  • If you want to be incloseMethod does something when it throws an exception.
  • Hidden objects can lead to problems that can never be found (although this should be extremely rare)
  • Making programmers lazier, well that’s a big drawback!

Because the side of some big guy actually do not know this grammar sugar, so suddenly want to write out.

A person who is not familiar with a syntax candy is not a master, but more familiar with a syntax candy, writing code will be more comfortable.


The more you read, the more you find your ignorance. Keep Fighting!

Welcome friendly communication, do not spray ~

Hope can help~