Java异常处理的十个建议,希望对大家有帮助~
本文已上传github:
https://github.com/whx123/JavaHome
公众号:捡田螺的小男孩
反例:
try{// do what you want}catch(Exception e){e.printStackTrace();}
正例:
try{// do what you want}catch(Exception e){log.info("你的程序有异常啦,{}",e);}
理由:
反例:
try{// do what you want}catch(Exception e){log.info("你的程序有异常啦");}
正例:
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){//仅仅捕捉 IOExceptionlog.info(“IOException in test,exception:{}”, e);}catch(SQLException e){//仅仅捕捉 SQLExceptionlog.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 {}//抛出父类Exceptionpublic static void test() throws Exception {}try {test(); //编译错误} catch (BizException e) { //捕获异常子类是没法匹配的哦log.error(e);}
正例:
//抛出子类Exceptionpublic 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);}
理由: