java異常處理技巧與原則總結

來源:互聯網
上載者:User

java的異常處理涉及到程式流程的跳轉,所以,虛擬機器需要儲存程式的執行流程,以便異常發生時能正確的跳轉,這也就導致了使用異常時會引起額外的開銷,所以,要謹慎地使用異常。
    使用異常有如下幾個原則:
    1、盡量避免使用異常,將異常情況提前檢測出來。
    2、不要為每個可能會出現異常的語句都設定try和catch。
    3、避免在方法中拋出(throw)或者捕獲(catch)運行時異常RuntimeException和Error。
    4、避免總是catch Exception或Throwable,而要catch具體的異常類。這樣可以使程式更加清晰。
    5、不要壓制、隱瞞異常。將不能處理的異常往外拋,而不是捕獲之後隨便處理。
    6、不要在迴圈中使用try...catch,盡量將try...catch放在迴圈外或者避免使用。
    7、在catch Exception中不只要處理異常,有時還要出棧、對前面的一些變數進行處理,否則可能出現bug
    示範執行個體

   package book.exception;

import java.util.Date;
import java.util.EmptyStackException;
import java.util.Stack;

/** *//**
* 使用異常的幾點注意
* @author joe
*
*/

public class ExceptionTips ...{
   
    public static void main(String[] args) ...{
       
        //(1)盡量避免使用異常,將異常情況提前檢測出來
        Stack<Object> stack = new Stack();
        try...{
            stack.pop();
        } catch (EmptyStackException e) ...{
            //....
        }
        //應該用下面的方式,以避免使用異常
        if (!stack.isEmpty()) ...{
            stack.pop();
        }
       
        //(2)不要為每個可能會出現的一場的語句都設定try和catch
        try...{
            stack.pop();
        } catch (EmptyStackException e) ...{
            //....
        }
        String data = "123";
        try ...{
            Double.parseDouble(data);
        } catch(NumberFormatException e)...{
            //....
        }
        //應該使用下面的方式,將兩個語句放在一個try塊中
        try...{
            stack.pop();
            Double.parseDouble(data);
        } catch(EmptyStackException e) ...{
            //....
        } catch(NumberFormatException e) ...{
            //....
        }
       
        //(3)避免在方法中拋出或者捕獲運行時異常RuntimeException和Error,
        //比如記憶體錯誤等
        //避免出現下面的情況
        String[] array;
        try ...{
            array = new String[1000];
            //array = new String[1000000];此時會出現OutOfMemoryError異常
        } catch (OutOfMemoryError e) ...{
            throw e;
        }
        //直接用下面代碼
        array = new String[1000];
       
        //(4)避免總是catch Exception或Throwable,而要捕獲具體的異常
        //這樣可以根據不同的異常做不同的處理,使程式更加清晰
        try ...{
            stack.pop();
            Double.parseDouble(data);
        } catch (Exception e) ...{
            //應該避免catch Exception !!!
        }
       
        //(5)不要壓制、隱瞞異常。將不能處理的異常往外拋,而不是捕獲之後隨便處理
        try...{
            Double.parseDouble(data);
        } catch (NumberFormatException e) ...{
            //.....
            throw e;    //拋出不能處理的異常,而不是隱瞞
        }
       
        //(6)不要在迴圈中使用try catch,盡量將try catch放在迴圈外或者避免使用try catch
        //下面的例子在迴圈中使用try和catch將耗費更多的時間,儘管沒有異常發生
        int i = 0;
        int ntry = 1000000;
        Stack s = new Stack();
        long s1;
        long s2;
        System.out.println("Testing for empty stack");
        s1 = new Date().getTime();
        for (i = 0; i <= ntry; i++) ...{
            if (!s.empty()) ...{
                s.pop();
            }
        }
        s2 = new Date().getTime();
        System.out.println((s2 - s1) + "milliseconds");
       
        System.out.println("Catching EmptyStackException");
        s1 = new Date().getTime();
        for(i = 0; i<=ntry; i++) ...{
            try ...{
                s.pop();
            } catch(EmptyStackException e) ...{
            }
        }
        s2 = new Date().getTime();
        System.out.println((s2 - s1) + "milliseconds");
    }

}
程式輸出:


Testing for empty stack
63milliseconds
Catching EmptyStackException
1922milliseconds

這樣的錯誤以前我也犯過,也見過不少人這樣的寫法。下面我也舉個例子:
 


 public void writeFile(File f) {
  String content = null;
  try {
   byte[] b = new byte[1024];
   FileInputStream in = new FileInputStream(f);
   in.read(b);
   content = new String(b);
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }

  if (content.indexOf("hello") > -1) {
   System.out.println("yes");
  } else {
   System.out.println("no");
  }
 }


 上面是個簡單的方法,代碼中有個隱藏的bug。我在維護一個系統的時候就遇到類似的代碼,實際中類似的BUG隱藏
的更深。在對系統業務和代碼不是很很熟悉的情況下,我推薦如下寫法:


  public void writeFile(File f) {
   String content = null;
   try {
    byte[] b = new byte[1024];
    FileInputStream in = new FileInputStream(f);
    in.read(b);
    content = new String(b);
   } catch (Exception e) {
    content="";
   //如果異常發生的話,content可能為空白
   //下面對content的操作就有可能發生NullPointerException異常
   System.out.println(e.getMessage());
  }
  //下面操作有可能發生NullPointerException異常
  if (content.indexOf("hello") > -1) {
   System.out.println("yes");
  } else {
   System.out.println("no");
  }
 }
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.