1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        你還在使用 try-catch-finally 關(guān)閉資源?

        共 6003字,需瀏覽 13分鐘

         ·

        2020-07-28 15:35

        熱文推薦:

        作者:何甜甜在嗎
        鏈接:https://juejin.im/post/5b8f9fa05188255c6f1df755

        代碼一定得寫的優(yōu)雅一點(diǎn)!

        你還在使用try-catch-finally關(guān)閉資源嗎,如果是,那么就有點(diǎn)out了。皮皮甜手把手教你使用?JDK7?引用的try-with-resource

        JDK7之前資源的關(guān)閉姿勢(shì):

        /**
        * jdk7以前關(guān)閉流的方式
        *
        * @author hetiantian
        * */
        public class CloseResourceBefore7 {
        private static final String FileName = "file.txt";

        public static void main(String[] args) throws IOException {
        FileInputStream inputStream = null;

        try {
        inputStream = new FileInputStream(FileName);
        char c1 = (char) inputStream.read();
        System.out.println("c1=" + c1);
        } catch (IOException e) {
        e.printStackTrace();
        } finally {
        if (inputStream != null) {
        inputStream.close();
        }
        }
        }
        }
        JDK7及以后關(guān)閉資源的正確姿勢(shì)

        try-with-resource Resource的定義:

        所有實(shí)現(xiàn)了?java.lang.AutoCloseable[1]?接口(其中,它包括實(shí)現(xiàn)了?java.io.Closeable[2]?的所有對(duì)象),可以使用作為資源。簡(jiǎn)單Demo進(jìn)行證實(shí):實(shí)現(xiàn)java.lang.AutoCloseable接口的Resource類:

        /**
        * 資源類
        *
        * @author hetiantian
        * */
        public class Resource implements AutoCloseable {
        public void sayHello() {
        System.out.println("hello");
        }

        @Override
        public void close() throws Exception {
        System.out.println("Resource is closed");
        }
        }
        測(cè)試類CloseResourceIn7.java
        /**
        * jdk7及以后關(guān)閉流的方式
        *
        * @author hetiantian
        * */
        public class CloseResourceIn7 {
        public static void main(String[] args) {
        try(Resource resource = new Resource()) {
        resource.sayHello();
        } catch (Exception e) {
        e.printStackTrace();
        }
        }
        }
        打印結(jié)果:
        hello
        Resource is closed

        當(dāng)存在多個(gè)打開資源的時(shí)候:資源二Resource2.java

        /**
        * 資源2
        *
        * @author hetiantian
        * */
        public class Resource2 implements AutoCloseable {
        public void sayhello() {
        System.out.println("Resource say hello");
        }

        @Override
        public void close() throws Exception {
        System.out.println("Resource2 is closed");
        }
        }

        測(cè)試類CloseResourceIn7.java

        /**
        * jdk7及以后關(guān)閉流的方式
        *
        * @author hetiantian
        * */
        public class CloseResourceIn7 {
        public static void main(String[] args) {
        try(Resource resource = new Resource(); Resource2 resource2 = new Resource2()) {
        resource.sayHello();
        resource2.sayhello();
        } catch (Exception e) {
        e.printStackTrace();
        }
        }
        }

        打印結(jié)果:

        hello
        Resource say hello
        Resource2 is closed
        Resource is closed

        即使資源很多,代碼也可以寫的很簡(jiǎn)潔,如果用JDK7之前的方式去關(guān)閉資源,那么資源越多,用fianl關(guān)閉資源時(shí)嵌套也就越多。

        那么它的底層原理又是怎樣的呢,由皮皮甜獨(dú)家揭秘優(yōu)雅關(guān)閉資源背后的密碼秘密

        查看編譯的class文件CloseResourceIn7.class:

        public class CloseResourceIn7 {
        public CloseResourceIn7() {
        }

        public static void main(String[] args) {
        try {
        Resource resource = new Resource();
        Throwable var2 = null;

        try {
        resource.sayHello();
        } catch (Throwable var12) {
        var2 = var12;
        throw var12;
        } finally {
        if (resource != null) {
        if (var2 != null) {
        try {
        resource.close();
        } catch (Throwable var11) {
        var2.addSuppressed(var11);
        }
        } else {
        resource.close();
        }
        }

        }
        } catch (Exception var14) {
        var14.printStackTrace();
        }

        }
        }

        可以發(fā)現(xiàn)編譯以后生成了try-catch-finally語(yǔ)句塊 finally中的var2.addSuppressed(var11);

        是不是有疑問?其實(shí)這么做是為了處理異常屏蔽的,我們將代碼修改一下。

        資源Resource.java

        /**
        * 資源類
        *
        * @author hetiantian
        * */
        public class Resource implements AutoCloseable {
        public void sayHello() throws Exception {
        throw new Exception("Resource throw Exception");
        }

        @Override
        public void close() throws Exception {
        throw new Exception("Close method throw Exception");
        }
        }

        兩個(gè)方法里面都拋出異常

        測(cè)試類CloseResourceIn7.java

        /**
        * jdk7及以后關(guān)閉流的方式
        *
        * @author hetiantian
        * */
        public class CloseResourceIn7 {

        public static void main(String[] args) {
        try {
        errorTest();
        } catch (Exception e) {
        e.printStackTrace();
        }
        }

        private static void errorTest() throws Exception {
        Resource resource = null;
        try {
        resource = new Resource();
        resource.sayHello();
        }

        finally {
        if (resource != null) {
        resource.close();
        }
        }
        }
        }

        打印結(jié)果:

        java.lang.Exception: Close method throw Exception
        at com.shuwen.Resource.close(Resource.java:15)
        at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:27)
        at com.shuwen.CloseResourceIn7.main(CloseResourceIn7.java:12)

        只打印了最后出現(xiàn)的異常【異常屏蔽】這樣會(huì)給開發(fā)人員排查錯(cuò)誤帶來一定的困難 我們換成try-with-resource方法實(shí)現(xiàn)CloseResourceIn7.java

        /**
        * jdk7及以后關(guān)閉流的方式
        *
        * @author hetiantian
        * */
        public class CloseResourceIn7 {

        public static void main(String[] args) {
        try {
        errorTest();
        } catch (Exception e) {
        e.printStackTrace();
        }
        }

        private static void errorTest() throws Exception {
        try(Resource resource = new Resource()) {
        resource.sayHello();
        }

        }
        }

        打印信息:

        java.lang.Exception: Resource throw Exception
        at com.shuwen.Resource.sayHello(Resource.java:10)
        at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:20)
        at com.shuwen.CloseResourceIn7.main(CloseResourceIn7.java:12)
        Suppressed: java.lang.Exception: Close method throw Exception
        at com.shuwen.Resource.close(Resource.java:15)
        at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:21)
        ... 1 more

        可以發(fā)現(xiàn),異常信息中多了一個(gè)Suppressed的提示,告訴我們這個(gè)異常其實(shí)由兩個(gè)異常組成,Close method throw Exception這個(gè)異常是被Suppressed【屏蔽】的異常

        怎么樣,是不是很簡(jiǎn)單呢,如果學(xué)會(huì)了話來個(gè)在看吧!

        參考資料

        [1]

        java.lang.AutoCloseable:?http://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html

        [2]
        java.io.Closeable:?http://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html


        如有收獲,歡迎分享?

        「點(diǎn)贊「評(píng)論?

        看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人

        ? 開發(fā)者全社區(qū)?

        5T技術(shù)資源大放送!包括但不限于:Android,Python,Java,大數(shù)據(jù),人工智能,AI等等。關(guān)注公眾號(hào)后回復(fù)「2T」,即可免費(fèi)獲取!!
        瀏覽 47
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产一区二区20p | 91亚洲精品一区二区三 | 伦理h动漫视频免费看 | 被老头摸添高潮呻吟 | 夜夜爱夜夜爽 | 日本电影一区二区三区高清 | 亚洲一区婷婷 | 男人操女人视频软件 | 欧美老妇性爱视频 | 涩涩视频免费看 |