Java常见异常处理
jinyangjie0 人气:0一、Java异常类层次结构
Java中,所有的异常都来源于java.lang包中的Throwable类,它有两个重要的子类,Exception(异常)和Error(错误)。
- Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。
- Error :Error 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获 。例如,虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会线程终止。
二、Throwable类常用方法
- public String getMessage(): 返回异常发生时的简要描述
- public String toString(): 返回异常发生时的详细信息
- public String getLocalizedMessage():返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
- public void printStackTrace():在控制台上打印 Throwable 对象封装的异常信息
三、try-catch-finally
- try块: 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
- catch块: 用于处理 try 捕获到的异常。
- finally 块: 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。
在以下 2种特殊情况下,finally 块不会被执行:
- 在 try 或 finally块中用了 System.exit(int)退出程序。但是,如果 System.exit(int) 在异常语句之后,finally 还是会被执行
- 程序所在的线程死亡。
代码示例:
BufferedReader br = null; try { br = new BufferedReader(new FileReader("test.txt")); br.readLine(); } catch (Exception e) { e.printStackTrace(); } finally { if (br != null) try { br.close(); } catch (IOException e) { e.printStackTrace(); } }
四、使用 try-with-resources 来代替try-catch-finally
1. 适用范围(资源的定义): 任何实现 java.lang.AutoCloseable
的对象
2. 关闭资源和 finally 块的执行顺序: 在 try-with-resources
语句中,任何 catch 或 finally 块在声明的资源关闭后运行
《Effecitve Java》中明确指出:
面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。
将上面的代码例子改造:
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { br.readLine(); } catch (Exception e) { e.printStackTrace(); }
代码变得非常简洁。
注意:try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值。
五、自定义异常
在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。
因为父类已经把异常信息的操作都完成了,所在子类只要在构造时,将异常信息传递给父类通过super 语句即可。
代码示例:
public class CustomException extends Exception { //无参构造方法 public CustomException(){ super(); } //有参的构造方法 public CustomException(String message){ super(message); } // 用指定的详细信息和原因构造一个新的异常 public CustomException(String message, Throwable cause){ super(message,cause); } //用指定原因构造一个新的异常 public CustomException(Throwable cause) { super(cause); } }
按照国际惯例,自定义的异常应该总是包含如下的构造函数:
- 一个无参构造函数
- 一个带有String参数的构造函数,并传递给父类的构造函数。
- 一个带有String参数和Throwable参数,并都传递给父类构造函数
- 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。
finally块和return
首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。
finally中的return 会覆盖 try 或者catch中的返回值。
finally中的return或异常会抑制(消灭)前面try或者catch块中的异常。
总结
加载全部内容