目录
1. 概念
1.1 异常
程序运行过程中产生的错误或问题。
1.2 异常处理
运用代码对异常处理的过程。
1.3 Java中的异常类
异常的顶级父类:java.lang.Throwble
Throwble的子类:Error、Exception
Exception的子类:checked异常、unchecked异常
1.4 checked异常 与 unchecked异常
checked异常:代码需要处理 API 抛出的 checked exception,要么用 catch 语句,
要么直接用 throws 语句抛出去。可以理解为编译时异常。
unchecked异常:也称 RuntimeException(运行时异常)。特点:代码不需要处理它们的异常也能通过编译。
RuntimeException不需要try...catch...或throws 机制去处理的异常。运行时异常。
2. 异常处理的相关的5个关键词
try:try块,可能会产生异常的代码
catch:catch块,如果异常产生,则捕获异常
finally:finally块,无论异常是否产生,finally块的代码都运行,一般用做资源的回收
throws:抛出异常,不主对处理,抛给调用者处理
throw:引发异常。根据代码逻辑,主对引发异常,主动引发异常后,方法需要显示的抛出
问题:final 与 finally 的区别?
答:final关键字,修饰类不能再派生新的子类;将变量或方法声明为final,可以保证他们使用中不被改变,
被声明为final的变量必须在声明时给定初值,而以后的引用中只能读取,不可修改,被声明为final的方法也同样只能使用,不能重载。
在异常处理时使用finally,finally块,无论异常是否产生,finally块的代码都运行,一般用做资源的回收。
3. 异常捕获
4. 打印异常
5. 常见的异常及说明
6. 常见异常的实例
//@Test
public void test01() {
File file=new File("D://xxx.txt");
InputStream inputStream = null;
try {
//可能会产生异常的代码
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
//打印异常信息--非必须
e.printStackTrace();
} finally {
//一定运行的代码,一般进行资源的显示回收
if(inputStream!=null) {
try { //try-catch嵌套
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//@Test
public void test02() {
//java中被0除是一种异常,类似的异常通常为RunTimeException
int t=9/0;
//下标越界异常也是RunTimeException--运行时异常
int[]array = new int[3];
array[1] = array[4]; //下标越界
}
//异常的抛出
@Test
public void test03() {
//调用方法
try {
method04();
//该方法抛出了异常:处理方法(1)继续抛出;(2)捕获异常
//此处选择捕获异常
} catch (FileNotFoundException e) {
System.out.println(e); //输出异常
}
}
public void method04() throws FileNotFoundException {
//throws FileNotFoundException--将异常抛出给调用者
InputStream inputStream = new FileInputStream(new File("D://xxx.txt"));
}
7. 自定义的异常
自定义的异常类与普通类无太大差别,只需继承Throwable 或者 Exception 类(或者Exception类的子类)即可。
自定义的异常类通常继承Exception 类。
7.1 自定义异常的实例
package com.company.exceptiontest;
//自定义异常类
public class MyException extends Exception {
//1. 序列化id--使用默认的
private static final long serialVersionUID = 1L;
//2. 重写toString
public String toString() {
return "我的异常";
}
}
package com.company.exceptiontest;
// 产生异常的类
public class CheckCount {
public void method1(int count) throws Exception {
if (count < 0) {
//当count < 0 ,引发异常
throw new Exception("数目异常");
//引发异常的方法必须抛出异常----throws Exception
}
}
public void method2(int count) throws MyException{
if(count>100) { //throws MyException--引发异常后必须显示抛出
throw new MyException(); //引发异常
}
}
}
//@Test
//调用自定义的异常
public void test04() {
CheckCount checkCount = new CheckCount();
try {
checkCount.method1(-1);
} catch (Exception e) {
//e.printStackTrace(); //打印信息的异常信息
System.out.println(e); //只打印错误类型
}
}
@Test
//调用自定义的异常
public void test05() {
CheckCount checkCount = new CheckCount();
try {
checkCount.method2(120);
} catch (MyException e) {
//e.printStackTrace(); //打印信息的异常信息
System.out.println(e); //只打印错误类型
}
}
运行结果:
8. 异常总结
8.1 不同的异常处理策略
关键性应用--处理所有异常
实验软将--处理部分异常
8.2 处理异常的原因
8.3 处理异常时的注意事项
尽可能就近处理异常,这样程序更清晰易读。
能处理的局部异常尽量不抛出。
不该将try-catch用于流程控制,异常的处理是非经常性的。
try可接多个catch,但是catch块的子类在前,父类在后,因为父类异常会捕捉子类异常,我们尽可能让异常捕捉详细。(下图)