该如何处理异常
- 向用户通告错误;
- 保存所有的工作结果;
- 允许用户以妥善的形式退出程序。
使用
一:创建异常类
- 构造函数
- 方法printStackTrace 与 getMessage(),可见名思意
public class MyException extends Exception{
public MyException(String message) {
super(message);
}
@Override
public String getMessage() {
return super.getMessage();
}
@Override
public void printStackTrace() {
super.printStackTrace();
}
}
调用printStackTrace()
的结果分析
Exception:message
at Main.main(Main.java:4)
二:可能产生异常的方法中
public class Bar {
private int id;
public void setId(int id) throws MyException {
if (id < 0) {
throw new MyException("negative number is not allowed");
}
this.id = id;
}
}
三:可能会产生异常的方法被调用时
a. catch处理
Bar bar = new Bar();
try {
bar.setId(-1);
} catch (MyException e) {
e.printStackTrace();
}
b. 继续抛出
public static void method2() throws MyException {
Bar bar = new Bar();
bar.setId(-1);
}
在这里bar.setId(-1);
将产生异常,我们没有try包围它但IDE并没有给出错误,不要这么做,我们看不见异常产生在哪里。
c. 包装
一个声明了Throwable cause
的异常类
public class ValueException extends Exception {
public ValueException(Throwable cause) {
super(cause);
}
@Override
public void printStackTrace() {
super.printStackTrace();
}
}
包装的过程
public static void method2() throws ValueException {
Bar bar = new Bar();
try {
bar.setId(-1);
} catch (MyException e) {
throw new ValueException(e);
// or
// ValueException valueException = new ValueException();
// valueException.initCause(e);
}
}
pulic void doSomething(){
try{
method2();
} catch (Exception e){
e.getCause();
}
}
四:finally
在throw执行之前执行一些必要的操作,如资源的释放。
不管是否有异常背异常,finally子句中的代码都被执行。
注意,如果方法需要返回一个值,finally中有返回时其他的返回将被替换。
但在catch中返回一个函数时return function();
,function
将被执行,返回值同样被替换。
异常的分类
graph TD;
Throwable-->Error;
Throwable-->Exception;
Exception-->IOException;
Exception-->RuntimeException;
派生于Error及RuntimeException的所有异常类称为未检查异常,所有其他异常称为已检查异常。
已检查错误通常并非是代码错误所造成的。
使用异常机制的技巧
- 选择合适的异常类型,以保证精确性
- 利用异常层次结构
- 某个很少发生的异常用空
catch{}
关闭它 - 早抛出,晚捕获