Java基础_异常处理

J1.基础结构

Thowable与其他异常关系

  • 所有的异常都是从Thowable继承而来,他下属有俩分支(如图所示)
  • Error:主要描述Java运行时系统的内部错误和资源耗尽错误
  • RuntimeException:由程序错误导致的异常
  • 记忆方法:抛出Error是Java编译器的锅,抛出RuntimeEception就是你的锅

派生于RuntimeException的异常

  • 错误类型转换
  • 数组访问越界
  • 访问null指针
    非派生于RuntimeException的异常
  • 试图在文件尾部读取数据
  • 试图打开一个不存在的文件
  • 视图根据给定的字符串查找class对象,事实上该字符串指代的class并不存在

Java语言规范规定如下
派生于Error或者RuntimeException类的所有异常称为“非受查异常”
除以上两者外的所有异常都是“受查异常”


声明受查异常

两个重要准则

  • 不要声明JAVA的内部错误,如从Error中继承的错误
  • 不要声明任何非受查类的错误,比如RuntimeException
  • (注意)所有的非受查异常都无法人为控制,所以应当尽量避免抛出

如果一个方法会抛出异常,那么应当在该方法的尾部声明所有可能抛出的异常
抛出的异常大于等于2个时,他们之间使用逗号分隔开

public FileInputStream(String name) throws FileNotFoundException

四种应当抛出异常的情况

  1. 调用一个抛出受查异常的方法
  2. 程序运行时发现错误,需要throws一个受查异常排查错误
  3. 程序出错
  4. JAVA虚拟机和运行时库出现的内部错误
  5. (可选) 针对可能会被其他人使用的方法,应当声明可能抛出的异常

如果父类的方法没有抛出任何受查异常,那么他的子类也不可以抛出任何异常;
然而一旦抛出了异常,就无法检测是父类还是子类抛出的异常


使用已存在异常类抛出异常步骤
首先找到合适的异常类->创建该异常类对象->抛出异常

EOFException:输入时遇见未预期的EOF时抛出异常(他还接受一个字符串参数,用来在抛出后显示出的反馈文本)

public String readData(Scanner in) throws EOFException {
        if(!in.hasNext()){
            throw new EOFException("EOF错误!");
        }
        return "";
    }

创建异常类
直接派生于某异常类,之后为该自定义异常类添加俩构造函数

  • 一个是默认构造函数
  • 一个是带有详细描述信息的构造函数,thowable的tostring方法会打印该详细信息
class FileFormatException extends IOException{
    public FileFormatException() {
        super();
    }
    public FileFormatException(String message, Throwable cause) {
        super(message, cause);
    }
}


J2.异常捕获

异常捕获的两种形式

第一种:自产自销;即在本方法中使用try…catch…语句来处理异常

  • try内写语句,这些语句中会抛出某些受查异常
  • catch用来捕获try中语句抛出的异常,一般每次只能捕获一个异常类,但也可以捕获多个(后面讲)
  • 自产自销的原因就是我们在一个方法内就把异常处理解决掉了,免去了调用者的后顾之忧
    public void read1(String filename){
        try {
            InputStream is = new FileInputStream(filename);
            int b;
            while ((b=is.read())!=-1) System.out.println(b);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

第二种:丢锅;如我们之前介绍的类型,在方法首部使用throws抛出指定异常

  • 该方法表示,把异常处理交给调用者管,本方法只需要侦测出异常并上报即可
  • (注意)以下代码和第一种方法实现的内容是一致的,只是改变了异常的处理方式而已
    public void read2(String filename) throws IOException{
        InputStream is = new FileInputStream(filename);
        int k;
        while ((k=is.read())!=-1) System.out.println(k);
    }

catch多个异常
一下代码展现使用方法,但有如下规定

  • 多个异常类使用或运算符隔开,这意味着只要有一个异常触发,另一个就无法使用
  • 连写的异常类必须没有子类关系,也就是说他们不能有相同的父类!
try{...}
catch (FileNotFoundException | UnknownHostException e){...}

再次抛出异常与异常链

我们可以在catch语句捕获到原始异常后,再抛出另一个类型的异常(以下方代码为例)

  • 可以把原异常作为新异常的原因包装起来然后抛出,那么后续我们就可以同时获取到原始异常和新异常的信息
  • 再次抛出异常的原因就是为了改变异常的类型
  • 该代码将SQLException异常转换为ServerException异常然后抛出

这一技巧当你只是为了获取异常中的某些参数而不愿做出任何回应时很有用

        try{}
        catch (SQLException e){
            Throwable se = new ServerException("database error");
            se.initCause(e);
            throw se;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhillery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值