Java异常处理(异常概念、异常分类、异常的捕获和处理)
文章目录
一、Java异常的概念
- Java异常是Java提供的用于处理程序中错误的一种机制。
- 所谓错误是指在程序运行过程中发生的一些异常事件(如除以0溢出、数组下标越界、读取的文件不存在等等)。
- 设计良好的程序应该在异常发生时提供处理这些错误的方法,使得程序不会因为异常的发生而阻断或产生不可预见的结果。
- Java程序执行过程中如出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并将其提交给Java运行时系统,这个过程称为抛出(throw)异常。
- 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。
- Java的异常指的是运行过程中出现的错误,观察错误的名字和出错的行号最重要,因为Java往往在出错的时候会告诉你出现的是什么错误,是在哪一行出现的错误。
常见的错误如下:
package com.lfq.exceptionhandler;
public class TextEX {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[4]);//数组越界异常
}
}
package com.lfq.exceptionhandler;
public class TextEX {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[1] / 0);//除以0溢出
}
}
二、一个例子:
//语法格式
public void someMethod() throws SomeException,IOException,FileNotFoundException...{
//声明该方法使用throws关键字抛出可能发生的异常
if(someCondition()){
//构造抛出异常对象,方法体中使用throw抛出异常这个异常对象
throw new SomeException(“错误原因”)
}
}
try{//调用该方法是试图捕获someMethod()方法抛出的异常
someMethod();
}catch(SomeException e){
//异常处理代码
//e.printStackTrace();//可以打印具体出错信息,便于调试
}catch(IOException e){
//打印信息,如除以0异常,会得到by zero的提示
e.getMessage();
}catch(FileNotFindException e){
e.printStackTrace();
}catch(....){
...
}finally{//使用finally进行文件关闭、删除临时文件、关闭数据库等操作
...
}
//具体例子
void m(int i) throws ArithmeticException{ //声明方法的同时抛出异常
if(i == 0){
throws new ArithmeticException("除数等于零");
}
}
TestEX testEX = new TestEX();//TestEX就是一个普通的测试类
try{
textEx.m(0);//这时候运行就会抛出异常,必须使用try catch或者继续使用throws向上抛出
}catch(Exception e){
e.printStackTrace();
}
三、异常的分类
J2SDK中定义了很多异常类,这些类对应了各种各样可能出现的异常事件。
分类详情如下图所示:
Error:称为错误,由Java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不做处理。
Exception:所有异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显式的声明或者捕获。
**Runtime Exception:**一类特殊的异常,如除数为0、数组下标越界等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大,因此,由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。
四、异常的捕获和处理
try{
//可能抛出异常的语句
}catch(SomeException e){
... ...
}catch(SomeException2){
... ...
}finally{
... ...
}
- try代码段包含可能产生异常的代码。
- try代码段后跟有一个或多个catch代码段。
- 每个catch代码段声明其能处理的一种特定类型的异常并提供处理的方法。
- 当异常发生时,程序会终止当前的流程,根据获取异常的类型去执行相应的catch代码段。
- finally段的代码无论是否发生异常都会执行。
- 异常的捕获和处理图如下图所示:
五、try语句
- try{…}语句指定了一段代码,该段代码就是监视代码有可能发生异常的范围。
- 在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做出对应的处理。
- 如果没有异常发生,所有的catch代码段都被略过不执行。
六、catch语句
- 在catch语句块中是对异常进行处理的代码,每个try语句块可以伴随一个或者多个catch语句,用于处理可能发生的不同类型的异常对象。
- 在catch中声明的异常对象(catch(SomeException))封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。
例如:
- getMessage()方法用来得到有关异常事件的信息,get zero等
- printStachTrace()方法,用来跟踪异常事件发生时打印堆栈的信息。
七、finally语句
- finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前能够对程序的状态作统一管理。
- 无论try所指定的程序块中是否抛出异常,finally所指定的代码都会被执行。
- 通常在finally语句中进行资源的清除工作。如:关闭打开的文件,删除临时文件等等。
八、使用自定义异常
- 使用自定义异常一般有如下步骤:
- 通过继承java.lang.Exception类声明自己的异常类
- 在方法适当的位置生成自定义异常的实例,并用throw语句抛出
- 在方法的声明部分用throws语句声明该方法可能抛出的异常。
例如:
class MyException extends Exception{
private int id;
public MyException(String message,int id){
super(message);
this.id = id;
}
public int getId(){
return id;
}
}
//使用自定义的异常
public class Test{
public void register(int num) throws MyException{
if(num < 0){
throw new MyException("人数为负值,不合理",3);
}
System.out.println("登记人数 " + num);
}
public void manager(){
try{
register(100);
}catch(MyException e){
System.out.println("登记失败,出错类型码= " + e.getId() );
e.printStackTrace();
}
System.out.println("操作结束");
}
public static void main(String []args){
Test t = new Test();
t.manager();
}
}
九、重写方法需要抛出与原方法所抛出异常类型一致的异常或者不抛出异常。
注意:异常类型一致指的是必须是完全一样的,范围大了或者小了都不行!
例如:
class A{
public void method() throws IOException(){...}
}
class B1 extend A{//报错,和父类的异常类型不一样
public void method() throws FileNotFoundException{...}
}
class B2 extends A{//报错,和父类的异常类型不一样
public void method() throws Exception{...}
}
public B4 extends A{//报错,和父类相比存在不一样的异常类型
public void method() throws IOException,MyException{...}
}
class B3 extends A{//正确
public void method() {...}
}
十、总结
- 一个图(异常的分类)
- 五个关键字,try,catch,finally,throws,throw
- catch异常的顺序,先捕获范围小的,再捕获范围大的
- 异常和重写的关系。