异常处理

异常处理

一、异常

  1. 异常指程序运行过程中出现的非正常现象,例如用户输入错误,除数为零,需要处理的文件不存在,数组下标越界等。

  2. 在Java异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类,异常类定义中包含了该类异常的信息和对异常进行处理的方法

二、异常处理

  1. 异常处理就是程序在出现问题时依然可以正确的执行完

  2. Java 采用面向对象的方式来处理异常:

  • 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。

  • 捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常,JRE在方法的调用栈中查找,从生成异常的方法回溯,直到找到相应的异常处理代码为止。

三、异常分类

在这里插入图片描述

  1. Exception是程序本身能够处理的异常,比如NullPointerException(空指针异常)、ArrayIndexOutOfBoundsExceptio(数组下标越界异常)、ArithmeticException(算术异常)等
    Exception类是所有异常的父类,其子类对应了各种各样可能出现的异常事件

  2. Error是程序无法处理的错误,表示运行应用程序中较严重的问题,大多数错误与编写代码执行者的操作无关,表示代码运行时JVM出现的问题,比如JVM运行错误(VirtualMachineError)、当JVM不再有继续执行操作所需的内存资源时,将出现OUtOfMemoryError,这些异常发生时,JVM一般会选择线程终止。综上,Error表明JVM已经处于不可恢复的崩溃状态。

四、运行时异常(RuntimeException)

派生于RuntimeException的异常,产生比较频繁,如果显式的声明或捕获将会对程序的可读性和运行效率有很大影响,因此系统自动检测并将它们交给缺省的异常处理程序
这类异常通常是由编程错误导致的,所以在编写程序时并不要求使用异常处理机制来处理这类异常,只需要添加逻辑处理来避免这些异常

  1. 算术异常
public class TestDemo1 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        System.out.println(a/b);
    }
}
  • 运行结果:

在这里插入图片描述

  • 修改代码:
public class TestDemo1 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        if (b != 0) {
        System.out.println(a/b);
        }
    }
}
  1. 空指针异常
public class TestDemo1 {
    public static void main(String[] args) {
        String str = null;
        str.length();
        //System.out.println(str)
    }
}
  • 运行结果:

在这里插入图片描述

  • 修改代码:
public class TestDemo1 {
    public static void main(String[] args) {
        String str = null;
        if (str != null) {
        System.out.println(str.length());
        }
    }
}
  1. 数组越界异常
public class TestDemo1 {
    public static void main(String[] args) {
        int[] array = new int[5];
        System.out.println(array[5]);
    }
}
  • 运行结果:

在这里插入图片描述

  • 修改代码:
public class TestDemo1 {
    public static void main(String[] args) {
        int[] array = new int[5];
        int a = 5;
        if (a < array.length) {
            System.out.println(array[a]);
        }
    }
}

四、已检查异常(CheckedException)

所有不是RuntimeException的异常统称为CheckedException,如IOException等用户自己定义的Exception异常,这类异常在编译时就必须做出处理,否则无法通过编译。
异常处理的方式有两种:

  • 使用try/catch捕获异常
  • 使用throws声明异常
  1. 捕获异常

是通过3个关键词实现:try-catch-finally

  用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉并处理它(catch),最后一步4是通过finally语句为异常处理提供一个统一的出口,finally所指定的代码都要被执行。

  • try:
    try语句指定了一段代码,该段代码就是异常捕获并处理的范围,在执行过程中,当任意一条语句产生异常时,就会跳过该条语句中后面的代码,代码中可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理
    当异常处理的代码执行结束后,不会回到try语句中执行尚未执行的代码,且一个try块必须有至少一个catch块或者一个finally块。

  • catch:
    一个try语句块可以伴随一个或者多个catch语句块,用于产生不同类型的异常对象

  • finally:
    有些语句不管是否发生了异常都必须要执行,就将这些语句放到finally块中。

try-catch-finally语句的执行过程:
首先执行可能发生异常的try语句块,如果try语句没有出现异常则执行完后跳转至finally语句块执行,若try语句出现异常则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理,catch语句块可以有多个,分别捕获不同类型的异常,catch语句块执行完后程序会执行finally语句块,finally是可选的,如果有的话,不管是否发生异常,finally块都会被执行。

即使try和catch块中存在return语句,finally语句也会执行,是在执行完finally语句后再通过return退出,
finally语句块只有一种情况下不会执行,在执行finally之前遇到了System.exit(0)结束程序运行。

例:
在D盘下创建一个a.txt,写入Daria.

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class TestDemo1 {
    public static void main(String[] args) {
        FileReader reader = null;
        try {
            reader = new FileReader("d:/a.txt");
            char ch = (char)reader.read();
            System.out.println(ch);
            char ch1 = (char)reader.read();
            System.out.print(ch1);
            char ch2 = (char)reader.read();
            System.out.print(ch2);
            char ch3 = (char)reader.read();
            System.out.print(ch3);
            char ch4 = (char)reader.read();
            System.out.print(ch4);
        } catch (FileNotFoundException e) { //子类异常在父类前面
            e.printStackTrace();    //打印异常信息
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述

  1. 声明异常
  • 当CheckedException产生时,不一定要立刻处理它,可以再把异常抛出去;
  • 在方法中使用try-catch是由这个方法来处理异常,但是在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理;
  • 如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,应根据异常规范在方法首部声明该方法可能抛出的异常;
  • 如果一个方法抛出多个已检查异常,就必须在方法的首部列举出所有异常,中间用逗号隔开。
    例:
    将上一段代码的捕获异常改为声明异常。
import java.io.FileReader;
import java.io.IOException;
public class TestDemo1 {
    public static void main(String[] args) throws IOException { //main方法将异常抛出给JRE
        readMyFile();
    }
    public static void readMyFile() throws IOException{
        FileReader reader = null;
        reader = new FileReader("d:/a.txt");
        System.out.println("=====================");
        char ch = (char)reader.read();
        System.out.print(ch);
        if (reader != null) {
            reader.close();
        }
    }
}

五、自定义异常

  1. 在程序中,如果jdk提供的任何标准异常类都无法充分描述我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类;
  2. 自定义异常类只需从Exception类或者它的子类派生一个子类即可;
  3. 自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理,如果不想处理可以让自定义异常类继承运行时异常RuntimeException类;
  4. 习惯上自定义异常应该包含两个构造器:一个是默认构造方法,另一个是带有详细信息的构造方法。

注意:

  1. 要避免使用异常处理代替错误处理;
  2. 只在异常情况下使用异常机制;
  3. 应将整个任务包装在一个try块中;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值