1.概念-》什么是异常

异常是导致程序中断运行的一种指令流。
Java的异常机制可以保证程序在出现异常后还可以继续进行处理,而不是立即闪退。

2.异常的继承结构

Java异常主要分为两类Exception和Error,他们都是继承自Throwable类(这个类竟然不是接口或者抽象类)。

Error(不可预知的)

一般是JVM错误,包括JVM的内部错误和资源耗尽错误(例如OOM)。这种错误应该尽量避免,出错了也无法进行阻止,只能让程序进行关闭。

Exception(可预知处理的)

一般是指程序开发的问题,可以通过try…catch语句进行避免。一般又分为RuntimeException和其他的Exception。
RuntimeException
RunTimeException继承自Exception类,和Error一样都是非检查性异常,可以不使用try…catch进行处理,直接将异常抛给JVM处理,当然这样程序也会停止。RuntimeException常见的子类如下:
其他异常
直接继承自Exception的异常类,必须显式的用try…catch语句进行异常处理或者抛出,由高级调用者进行处理,否则编译就会不通过


image.png

异常的两种处理方式

1.throw
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行
2.throws
声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。
关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).

3.异常处理基本原则

  1. 3.1 如果你不能处理异常,不要捕获该异常。<br /> 3.2 如果要捕获,应在离异常源近的地方捕获它。<br /> 3.3 不要吞没你捕获的异常。<br /> *(就是捕获的异常,但是什么也不做)<br /> 3.4 除非你要重新抛出异常,否则把它log起来。<br /> 3.5 当一个异常被重新包装,然后重新抛出的时候,不要打印statck trace。<br /> 3.6 用自定义的异常类,不要每次需要抛出异常的时候都抛出java.lang.Exception。方法的调用者可以通过throws知道有哪些异常需要处理--所以它是自我描述的。<br /> 3.7 如果你编写业务逻辑,对于终端用户无法修复的错误,系统应该抛出非检查的异常(unchecked exception);如果你编写一个第三方的包给其他的开发人员用,对于不可修复的错误要用需要检查的异常(checked exception)。<br /> 3.8 绝对不要因为写throws语句会让你用起来不舒服,而不声明需要检查的异常。<br /> 3.9 应用级别的错误或不可修复的系统异常用非检查的异常(unchecked exception)抛出。<br /> *(注意是错误,意味着不可修复,比如配置文件错误)<br /> 3.10 根据异常的粒度组织你的方法

自定义异常

按照国际惯例,自定义的异常应该总是包含如下的构造函数:

  • 一个无参构造函数
  • 一个带有String参数的构造函数,并传递给父类的构造函数。
  • 一个带有String参数和Throwable参数,并都传递给父类构造函数
  • 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

下面是IOException类的完整源代码,我们可以参考:
public class IOException extends Exception {
static final long serialVersionUID = 7818375828146090155L;
public IOException() {
super();
}
public IOException(String message) {
super(message);
}
public IOException(String message, Throwable cause) {
super(message, cause);
}
public IOException(Throwable cause) {
super(cause);
}
}

注意:

  1. System.out.println是高代价的。调用System.out.println会降低系统吞吐量。
    2. 在生产环境中别用异常的printStackTrace()方法。printStackTrace默认会把调用的堆栈打印到控制台上,在生产环境中访问控制台是不现实的。

思考:

public static void main(String[] args) {
int test = test();
System.out.println(test);
}

private static int test() {
try {
System.out.println(“try”);
int i = 1 / 0;
return 1;
}catch (Exception e){
System.out.println(“catch”);
return 2;
}finally {
System.out.println(“finally”);
}
}
打印的数据会是什么?