一。异常: 就是不正常的意思
在编译或者运行的过程中,可能会出现的问题。我们是把这些问题提前暴露出来。
在程序中,运行的过程中,出现了非正常的情况,最终导致JVM的非正常停止。
Java是面向对象语言,会出现一些问题,就将这些问题 封装成 类,描述问题这样的类,我们就成为异常类
产生异常就是 创建异常对象并抛出该对象,java的处理就是中断处理。
我们见过一些异常
类型转换异常
索引越界异常
空指针异常
1.异常的体系
Throwable
|-- Error 错误 系统级别的 不能处理只能尽量避免
和语法错误是不一样的,
|-- Exception 异常 代码级别的 异常产生后 我们可以针对性的进行纠正 让程序继续执行
2.Exception的分类
编译期异常 checked异常 : 必须要处理,如果不处理编译不通过
在编译时期,编译器就会检查,如果没有处理异常,则编译失败。(日期格式化异常)
如果运行时出问题,照样会报出来
将.java生成.class文件的过程
除了RuntimeException以及他的子类,都属于编译时期异常。在编译阶段必须要处理。
运行期异常 runtime异常:可以处理也可以 不处理
在编译期,运行期的异常不会被编译器检测,在运行时期报出来。(索引越界异常)
RuntimeException 以及 他的子类都是运行时期异常,在编译阶段可以处理和可以不处理。
3.如果有异常,我们得到的是哪些信息:
a> 异常名称
b> 异常的原因
c> 异常的位置(哪一行有错误)
我们得到的异常都是异常对象。这个异常对象需要对他进行处理,如果你当前代码处理不了
要把这个异常交给调用者,最终给jvm虚拟机-->会把信息打印到控制台
4.throw(关键字)用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
格式
throw new 异常类名(信息);
throw 使用方法内部,而且后面只能跟异常对象,而且只能跟一个异常对象。
注意
使用在方法内部 只能用来抛出异常对象
遇到了这个单词 那么该方法就结束运行
返回到调用者处
5.异常的处理方式
1:声明抛出 关键字 throws
使用在方法的声明上,后面跟的是异常类。可以跟一个,也可以跟多个。
声明异常的格式
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2..{
}
我们并没有对问题具体的解决,把一些信息打印到控制台,方便我们对象问题的解决。
2:捕获异常 关键字 try...catch..finally
try{//检测异常
可能出现异常的代码;
}catch(异常类名 e){//e 就代表 throw出来的异常对象 捕获异常
给出 处理方案
}
6.多异常处理
try{
可能出现异常的代码;
}catch(Exection e){//给一个比较大的异常类。
给出 处理方案
}
7. Throwable类中定义了一些查看方法:
- public String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。
- public String toString():获取异常的类型和异常描述信息(不用)。
- public void printStackTrace():打印异常的跟踪栈信息并输出到控制台。
包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
catch中 常见的三种处理方式
1:记录日志
2:打印异常信息
3:继续抛出异常 是将 编译期异常转换成 运行期异常的操作
8.finally(最终地) 关键字
在对异常进行处理的时候使用,配合 try...catch ... finally 一起使用
作用:
a> 清理垃圾
b> 释放资源
无论代码中有没有异常,会不会执行 catch ,finally都会被执行。
try{
可能出现异常的代码;
} catch(异常类名 e){
给出对应的处理
} finally{
必须要执行的的代码
}
补充:finally在正常情况下都会被执行,即使在catch语句中存在return.
public class Test01 {
public static void main(String[] args) {
try {
int a = 1 / 1;//找图片
}catch (Exception e){
System.out.println("catch 执行了");
return;//执行了return,但是并没有完全执行,只是获取了返回路径
//如果有finally会先去执行finally中的代码,然后去具体的返回
}finally {
System.out.println("finall执行了");//执行
//return;
}
System.out.println("=====================");//不会
}
}
9.使用异常的注意事项:
- 运行时异常被抛出可以不处理。即不捕获也不声明抛出。
- 如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。
- 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
- 当多异常处理时,捕获处理,前边的类不能是后边类的父类
- 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。
- 如果finally有return语句,永远返回finally中的结果,避免该情况.
10.自定义异常类
如何定义异常类
编译期异常 继承 Exception
在编译阶段 我们就必须给出处理方式 要么声明 要么捕获 否则编译失败
运行期异常 继承 RuntimeException
在编译阶段 我们不用必须给出处理方式,因为有默认的处理方式
不管哪种异常 出了 那么 最终程序员 都需要调整代码的
研究源码
NullPointerException 运行期异常类
public class NullPointerException extends RuntimeException {
public NullPointerException() {
super();
}
public NullPointerException(String s) {
super(s);
}
}
其实 写一个自定义异常类 很简单 只要 完成 继承对应的 异常类 Exception/RuntimeException
再写俩构造 就是一个自定义异常类