第一章 异常
1.1 异常概念
- 异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止
- 在java等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出一个异常对象,java处理异常的方式是中断处理
异常指的并不是语法错误!!
1.2 异常体系
- Throwable:异常的根类
- 子类:
- Error类:不能处理
- Exception类:可以避免
- 子类:
1.3 异常分类
- Exception:编译期异常,进行遍历(写代码)java程序出现的问题(必须处理)
- RuntimeException:运行期异常,java程序运行过程中出现的问题(无需处理)
- Error:错误(必须修改代码才能解决)
1.4 异常的产生过程解析
/*
JVM接收到了这个异常对象,做了两件事:
1.把异常对象(内容,原因,位置)以红色的字体打印在控制台
2.JVM会终止当前正在执行的java程序-->中断处理
*/
public static void main(String[] args) {
/*
main方法会把异常对象抛出给JVM
*/
int[] arr={1,2,3};
int e = getElement(arr,3);
System.out.println(e);
}
public static int getElement(int[] arr, int index){
/*
getElement方法会把异常对象抛出给main方法
*/
int ele = arr[index];
return ele;
}
第二章 异常的处理
java异常处理的五个关键字:try、catch、finally、throw、throws
2.1 抛出异常throw
- 作用:可以使用throw关键字在指定的方法中抛出指定的异常
- 格式:throw new xxxException(“异常产生的原因”)
- 注意:
- throw关键字必须写在方法的内部
- throw关键字后边new的对象必须是Exception或者Exception的子类对象
- throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
- throw关键字后边创建的是RuntimeException或者是RuntimeException的子类对象,我们可以不处理,默认交给JVM处理(打印异常对象、中断程序)
- 运行时异常:NullPointerException IndexOutOfBoundsException和它的子类ArrayIndexOutOfBoundsException
- throw关键字后边创建的是编译异常,我们就必须处理这个异常,要么throws,要么try…catch…
- 编译器异常:IOExcepetion和它的子类FileNotFoundException
- throw关键字后边创建的是RuntimeException或者是RuntimeException的子类对象,我们可以不处理,默认交给JVM处理(打印异常对象、中断程序)
2.2 Objects非空判断
-
方法:public static T requireNonNull(T obj):查看指定引用对象不是null
-
源码:
public static <T> T requireNonNull(T obj){ if(obj==null) throw new NullPointerException(); return obj; }
2.3 异常处理的两种方式
2.3.1 声明异常throws
- 作用:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,没有捕获处理,那么必须通过throws进行声明,让调用者去处理。
- 格式:修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
- 注意:
- throws关键字必须写在方法声明处
- throws关键字后边声明的异常必须是Exception或者Exception的子类对象
- 方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个对象
- 如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可
- 调用了一个声明抛出异常的方法,我们就必须处理声明的异常
- 要么继续使用throws声明抛出,交给方法的调用者,最终交给JVM
- 要么try…catch自己处理异常
2.3.2 捕获异常try…catch
-
作用:自己处理异常
-
格式:
try{ // 可能产生异常的代码 }catch(定义一个异常变量,用来接收try中抛出的异常对象){ // 产生异常对象后,怎么处理异常对象 }
-
注意:
- try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
- 如果try中产生了异常,那么就会执行catch中的异常处理逻辑,继续执行try…catch之后的代码;如果try中没有发生异常,就不会执行catch中的代码,直接执行try…catch之后的代码。
-
Throwable类:
-
打印异常信息的常用方法:
String getMessage(): 返回此throwable的简短描述 String toString(): 返回throwable的详细消息字符串 void printStackTrace(): JVM打印异常对象,默认此方法,打印的异常信息是最全面的
-
2.4 finally代码块
- finally:有一些特定的代码无论异常是否发生,都需要执行。
- 格式:在try…catch结尾处加上finally{}
- 注意:
- finally不能单独使用,必须和try一起使用
- finally一般用于资源释放(资源回收),无论程序是否异常,最后都要资源释放(IO)
2.5 异常注意事项
-
多个异常使用捕获又该如何处理呢?
-
多个异常分别处理
-
多个异常一次捕获,多次处理
注意:catch里边定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上边,否则就会报错
-
多个异常一次捕获,一次处理
-
-
运行时异常被抛出可以不处理,即不捕获也不声明抛出
-
如果finally有return语句,永远返回finally中的结果,避免该情况
-
父类异常什么样,子类异常就什么样
第三章 自定义异常
-
作用:java提供的异常类,不够我们使用,需要自己定义一些异常类
-
格式:
public class XXXException extends Exception / RuntimeException{ // 添加一个空参数的构造方法 // 添加一个带异常信息的构造方法 }
-
注意:
- 自定义异常类一般都是以Exception结尾,说明该类是一个异常类
- 自定义异常类,必须的继承Exception或者RuntimeException
- 继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理中这个异常,要么throws,要么try…catch
- 继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理
-
使用:
public class RegisterException extends Exception{ public RegisterException() { super(); } public RegisterException(String message) { super(message); } }