一 异常的概念
1.1 异常的概念
Java异常表示Java程序在运行期出现的错误,观察错误的名字和信号最重要
Java异常是Java提供的用于处理程序中错误的一种机制。
所谓错误是指在程序运行的过程中发生的一些异常事件。
设计良好的程序应该在异常发生时提供处理这些错误的方法,使得程序不会因为异常的发生而阻断或产生不可预见的结果。
Java程序的执行过程中如果出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常
二 异常的分类
2.1 异常的分类
-
Throwable:可以被抛出的
-
Error:不能处理的错误,如JVM虚拟机出现的问题
-
Exception:可以处理的异常
-
RuntimeException:运行时异常,表示可以处理,也可以不处理的
-
Other:其他异常,必须处理
-
-
三 异常的捕获和处理
3.1 异常的捕获和处理
try {
//可能抛出异常的语句
} catch (SomeException1 e) {
......
} catch (SomeException2 e) {
......
} finally {
......
}
-
try代码段包含可能产生例外的代码
-
try代码段后跟一个或多个catch代码段
-
每个catch代码段声明其处理的一种特定类型的异常并提供处理的方法
-
当异常发生时,程序会终止当前的流程,根据获取异常的类型去执行相应的catch代码段
-
finally段的代码无论是否发生异常都有执行(return前执行)
try语句指定了一段代码,该代码就是一次捕获并处理例外的范围。在执行的过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理。如果没有例外产生,所有的catch代码段都被略过不执行
catch语句块中是对异常进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。在catch中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息,例如:
-
getMessage()方法:用来得到有相关异常事件的信息
-
printStackTrace()方法:用来跟踪异常事件发生时执行堆栈的内容
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序的状态作统一的管理。无论try指定的程序块中是否抛出异常,finally所指定的代码都要被执行,通常在finally语句中可以进行资源的清除工作,如:
-
关闭打开的文件
-
删除临时文件
-
import java.io.*; public class TestEx { public static void main(String[] args) { FileInputStream in = null; try { in = new FileInputStream("myfile.txt"); int b; b = in.read(); while (b != -1) { System.out.print((char)b); b = in.read(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { System.out.println(e.getMessage()); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }
3.2 常见的异常类型
如下所示:
四 声明方法抛出的异常
4.1 声明方法抛出的异常
对于方法无法处理的异常,可以使用throws关键字将异常抛出,交给上级方法处理
import java.io.*;
public class TestEx {
public static void main(String[] args) {
try {
new TestEx().f2();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
void f() throws FileNotFoundException , IOException {
FileInputStream in = new FileInputStream("myfile.txt");
int b;
b = in.read();
while (b != -1) {
System.out.print((char)b);
b = in.read();
}
}
void f2() throws IOException , FileNotFoundException {
f();
}
}
4.2 自定义异常
当JDK中的异常类型不能满足程序的需要时,可以自定义异常类。步骤如下:
定义异常类 --> 编写构造方法,继承父类的实现 --> 实例化自定义异常对象 --> 使用throw抛出
继承Exception或者RuntimeException
-
一般要继承Exception(检查异常)或者继承RuntimeException(运行时异常)
-
一般要加上两个构造方法:无参的/有参的(参数是异常的原因)
-
有参的构造方法可以拓展
如下面一段代码
public class TestPerson {
public static void main(String[] args) {
Person p = new Person();
try {
p.setGender("人妖");
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println(p);
}
}
class Person {
private String gender;
public void setGender(String gender) throws GenderException{
if ("男".equals(gender) || "女".equals(gender)) {
this.gender = gender;
} else {
throw new GenderException("性别只能为男或者女");
}
}
public String getGender() {
return gender;
}
public String toString() {
return "Gender = " + gender;
}
}
class GenderException extends Exception {
String gender;
public GenderException() {
}
public GenderException(String message) {
super(message);
}
}
4.3 throw和throws区别
-
位置不同:throw在方法体中;throws在方法声明中
-
内容不同:throw后边是一个具体的异常对象;throws后边是异常的类型(类名)
-
作用不用:throw产生异常的源头(一般不处理);throws异常的声明,告诉方法调用者,需要处理
-
个数不同:throw只能扔出一个异常对象;throws可以声明多种异常