<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          最常見的10種Java異常問題

          共 5498字,需瀏覽 11分鐘

           ·

          2021-03-25 22:19

          封面:洛小汐

          者:潘潘

          前言

          本文總結了有關Java異常的十大常見問題。

          目錄

          1. 檢查型異常(checked) vs. 非檢查型異常(Unchecked)
          2. 異常管理的最佳實踐箴言
          3. 為什么在try代碼塊中聲明的變量不能在catch或者finally中被引用?
          4. 為什么 Double.parseDouble(null) 和 Integer.parseInt(null) 拋出的異常不一樣呢?
          5. Java中經常使用的運行時異常
          6. 我們可以在同一個catch子句中捕獲多個異常嗎?
          7. 在 Java 中構造方法能拋出異常嗎?
          8. 在 final 代碼塊中拋出異常
          9. try語句有return那么finally還會執(zhí)行嗎?
          10. 為何有些開發(fā)人員對異常置之不理?

          1.檢查型異常(checked) vs 非檢查型異常(Unchecked)

          簡單來說,對于檢查型異常, 一般在 編譯期 就會被檢查到,所以我們肯定會提前在方法內進行捕獲處理,或者在方法頭部申明并拋出。而非檢查型異常,往往無法提前預知,例如被除數(shù)是0、空指針等。檢查型異常特別重要,它會告訴那些調用你的接口的開發(fā)者們,如何提前預知并處理好這些可能發(fā)生的異常。

          例如,IOException就是常見的檢查型異常,而 RuntimeException(運行時異常)就是非檢查型異常。在閱讀剩余部分之前你或許可以研讀這份Java異常的層次結構圖。

          2.異常管理的最佳實踐箴言

          如果可以正確處理異常,則應將其捕獲并處理,否則應將其拋出。

          3. 為什么在try代碼塊中聲明的變量不能在catch或者finally中被引用?

          看下面這段代碼,在try代碼塊中聲明的 String s 就不能在catch中被引用, 這段代碼在編譯期是通不過的。

          try {
           File file = new File("path");
           FileInputStream fis = new FileInputStream(file);
           String s = "inside";
          catch (FileNotFoundException e) {
           e.printStackTrace();
           System.out.println(s);
          }

          原因是你不知道在try代碼塊中哪個位置會引發(fā)異常, 很有可能在聲明對象之前就引發(fā)了異常。對于這個特定的示例,是正確的。

          4.為什么 Double.parseDouble(null) 和 Integer.parseInt(null) 拋出的異常不一樣呢?

          它倆拋出的異常確實不同,但這是JDK的問題,當時開發(fā)這兩個接口的開發(fā)人員不是同一波,所以我們沒必要去糾結這個問題。

          Integer.parseInt(null); 
          // throws java.lang.NumberFormatException: null 

          Double.parseDouble(null); 
          // throws java.lang.NullPointerException

          5.Java中經常使用的運行時異常

          這里列舉一部分:

          IllegalArgumentException ArrayIndexOutOfBoundsException

          在有些場景某個目標對象不滿足我們的預期,會用到這些異常,例如下面在 if 判斷語句中被使用:

          if (obj == null) {
             throw new IllegalArgumentException("obj can not be null");

          6.我們可以在同一個catch子句中捕獲多個異常嗎?

          答案是當然可以,不過如果在同一個catch子句中捕獲的這些異常都直接或間接繼承自同一父類,那么就只能在catch子句中捕獲父類了。

          // Java 7 之前需要這樣
          catch (AException a) {
               logger.error(a);
               throw new MyException("a");
          catch (BException b) {
               logger.error(b);
               throw new MyException("b");
          }catch (CException c) {
               logger.error(c);
               throw new MyException("c");
          }

          // 在Java 7中,可以捕獲所有這些異常 
          catch(AException | BException | CException ex){
               logger.error(ex);
               throw new MyException(ex);
          }

          補充說明 : 其實是這樣,在 Java7 就開始支持catch子句捕獲多個異常,多個異常使用 XOR符號(I) 連接,異常的發(fā)生有可能是 A | B,但不能同時出現(xiàn),相當于這些異常不能是間接或直接繼承自同一個父類,因為如果AB都繼承同一父類,那就不能 A|B 都寫上,這也是繼承原則。

          7.在 Java 中構造方法能拋出異常嗎?

          答案是當然可以,構造方法僅是一種特殊方法而已。可以參考這個示例。

          class FileReader{
           public FileInputStream fis = null;
           
           public FileReader() throws IOException{
            File dir = new File(".");//get current directory
            File fin = new File(dir.getCanonicalPath() + 
                                    File.separator + "not-existing-file.txt");
            fis = new FileInputStream(fin);
           }
          }

          8.在 final 代碼塊中拋出異常

          下面這個寫法是合法的:

          public static void main(String[] args) {
           File file1 = new File("path1");
           File file2 = new File("path2");
           try {
           
            FileInputStream fis = new FileInputStream(file1);
           } catch (FileNotFoundException e) {
            e.printStackTrace();
           } finally {
            try {
             FileInputStream fis = new FileInputStream(file2);
            } catch (FileNotFoundException e) {
             e.printStackTrace();
            }
           }
          }

          但是為了獲得更好的代碼可讀性,你應該將把 try-catch代碼塊封裝成一個新方法,然后將方法調用放在finally子句中:

          public static void main(String[] args) {
           File file1 = new File("path1");
           File file2 = new File("path2");
           try {
           
            FileInputStream fis = new FileInputStream(file1);
           } catch (FileNotFoundException e) {
            e.printStackTrace();
           } finally {
                  // 封裝方法
            methodThrowException(); 
           }
          }

          9.try語句有return那么finally還會執(zhí)行嗎?

          答案是肯定會執(zhí)行。

          Java官方文檔描述:The finally block always executes when the try block exits

          意思就是 ” 只要存在try代碼塊,finally代碼塊就一定會執(zhí)行 ” ,這種特性可以讓程序員避免在try語句中使用return, continue或者break關鍵字而忽略了關閉相關資源的操作等。

          10.為何有些開發(fā)人員對異常置之不理?

          很多時候會見到下面這種代碼寫法。允許的情況下盡可能捕獲異常并且進行處理,不知道為什么很多開發(fā)人員就是這么干?

          try {
               ...
          catch(Exception e) {
               e.printStackTrace();
          }

          忽略異常是一件很容易做到的事,雖然這種寫法很常見,但不一定是正確的寫法。

          參考文獻:
          1. Unchecked exceptions in Java
          2. The root of Java exception class hierarchy
          3. Java exceptions related questions in stackoverflow

          譯文完,由于個人理解能力和知識寬度有限,譯文中存在失誤之處,還請見諒,歡迎指正。

          往期推薦

          大佬也hashcode方法上翻船了,不小心秀了一把!

          不要再滿屏寫 try...catch 了!這個更香!

          SpringBoot接口冪等性實現(xiàn)的4種方案!

          面試題:將字符串反轉的8種方法,你能想到幾種?

          面試題:重寫equals方法為什么通常會重寫hashcode方法?



          如果你覺得這篇文章不錯,那么,下篇通常會更好。添加微信好友,可備注“加群”(微信號:zhuan2quan)

          一篇文章就看透技術本質的人,
            和花一輩子都看不清的人,
            注定是截然不同的搬磚生涯。
          ▲ 按關注”程序新視界“,洞察技術內幕


          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品成人网站 | 天天干夜夜拍 | 亚洲欧美日韩激情 | 天堂网av免费 | 亚洲无码五月丁香 |