Java異常處理的十個建議,但願對你們有幫助~java
本文已上傳github:git
github.com/whx123/Java…github
公衆號:撿田螺的小男孩數據庫
反例:bash
try{
// do what you want
}catch(Exception e){
e.printStackTrace();
}
複製代碼
正例:框架
try{
// do what you want
}catch(Exception e){
log.info("你的程序有異常啦,{}",e);
}
複製代碼
理由:學習
反例:ui
try{
// do what you want
}catch(Exception e){
log.info("你的程序有異常啦");
}
複製代碼
正例:spa
try{
// do what you want
}catch(Exception e){
log.info("你的程序有異常啦,{}",e);
}
複製代碼
理由:日誌
反例:
public void test(){
try{
//…拋出 IOException 的代碼調用
//…拋出 SQLException 的代碼調用
}catch(Exception e){
//用基類 Exception 捕捉的全部可能的異常,若是多個層次都這樣捕捉,會丟失原始異常的有效信息哦
log.info(「Exception in test,exception:{}」, e);
}
}
複製代碼
正例:
public void test(){
try{
//…拋出 IOException 的代碼調用
//…拋出 SQLException 的代碼調用
}catch(IOException e){
//僅僅捕捉 IOException
log.info(「IOException in test,exception:{}」, e);
}catch(SQLException e){
//僅僅捕捉 SQLException
log.info(「SQLException in test,exception:{}」, e);
}
}
複製代碼
理由:
反例:
FileInputStream fdIn = null;
try {
fdIn = new FileInputStream(new File("/jay.txt"));
//在這裏關閉流資源?有沒有問題呢?若是發生異常了呢?
fdIn.close();
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
複製代碼
正例1:
須要使用finally關閉流資源,以下
FileInputStream fdIn = null;
try {
fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}finally {
try {
if (fdIn != null) {
fdIn.close();
}
} catch (IOException e) {
log.error(e);
}
}
複製代碼
正例2:
固然,也可使用JDK7的新特性try-with-resource來處理,它是Java7提供的一個新功能,它用於自動資源管理。
try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
// use resources
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
複製代碼
理由:
反例:
//BizException 是 Exception 的子類
public class BizException extends Exception {}
//拋出父類Exception
public static void test() throws Exception {}
try {
test(); //編譯錯誤
} catch (BizException e) { //捕獲異常子類是無法匹配的哦
log.error(e);
}
複製代碼
正例:
//拋出子類Exception
public static void test() throws BizException {}
try {
test();
} catch (Exception e) {
log.error(e);
}
複製代碼
反例:
public static void testIgnoreException() throws Exception {
try {
// 搞事情
} catch (Exception e) { //通常不會有這個異常
}
}
複製代碼
正例:
public static void testIgnoreException() {
try {
// 搞事情
} catch (Exception e) { //通常不會有這個異常
log.error("這個異常不該該在這裏出現的,{}",e);
}
}
複製代碼
理由:
反例:
public UserInfo queryUserInfoByUserId(Long userid) throw SQLException {
//根據用戶Id查詢數據庫
}
複製代碼
正例:
public UserInfo queryUserInfoByUserId(Long userid) {
try{
//根據用戶Id查詢數據庫
}catch(SQLException e){
log.error("查詢數據庫異常啦,{}",e);
}finally{
//關閉鏈接,清理資源
}
}
複製代碼
理由:
咱們經常會想要在捕獲一個異常後拋出另外一個異常,而且但願把原始異常的信息保存下來,這被稱爲異常鏈。公司的框架提供統一異常處理就用到異常鏈,咱們自定義封裝異常,不要丟棄原始異常的信息,不然排查問題就頭疼啦
反例:
public class TestChainException {
public void readFile() throws MyException{
try {
InputStream is = new FileInputStream("jay.txt");
Scanner in = new Scanner(is);
while (in.hasNext()) {
System.out.println(in.next());
}
} catch (FileNotFoundException e) {
//e 保存異常信息
throw new MyException("文件在哪裏呢");
}
}
public void invokeReadFile() throws MyException{
try {
readFile();
} catch (MyException e) {
//e 保存異常信息
throw new MyException("文件找不到");
}
}
public static void main(String[] args) {
TestChainException t = new TestChainException();
try {
t.invokeReadFile();
} catch (MyException e) {
e.printStackTrace();
}
}
}
//MyException 構造器
public MyException(String message) {
super(message);
}
複製代碼
運行結果以下,沒有了Throwable cause,很差排查是什麼異常了啦
正例:
public class TestChainException {
public void readFile() throws MyException{
try {
InputStream is = new FileInputStream("jay.txt");
Scanner in = new Scanner(is);
while (in.hasNext()) {
System.out.println(in.next());
}
} catch (FileNotFoundException e) {
//e 保存異常信息
throw new MyException("文件在哪裏呢", e);
}
}
public void invokeReadFile() throws MyException{
try {
readFile();
} catch (MyException e) {
//e 保存異常信息
throw new MyException("文件找不到", e);
}
}
public static void main(String[] args) {
TestChainException t = new TestChainException();
try {
t.invokeReadFile();
} catch (MyException e) {
e.printStackTrace();
}
}
}
//MyException 構造器
public MyException(String message, Throwable cause) {
super(message, cause);
}
複製代碼
反例:
try {
obj.method()
} catch (NullPointerException e) {
...
}
複製代碼
正例:
if (obj != null){
...
}
複製代碼
注意異常的匹配順序,由於只有第一個匹配到異常的catch塊纔會被執行。若是你但願看到,是NumberFormatException異常,就拋出NumberFormatException,若是是IllegalArgumentException就拋出IllegalArgumentException。
反例:
try {
doSomething("test exception");
} catch (IllegalArgumentException e) {
log.error(e);
} catch (NumberFormatException e) {
log.error(e);
}
複製代碼
正例:
try {
doSomething("test exception");
} catch (NumberFormatException e) {
log.error(e);
} catch (IllegalArgumentException e) {
log.error(e);
}
複製代碼
理由: