基础巩固--异常

Java语言规范讲派生于Error类或RuntimeException类的所有异常称为非受查异常,所有其他的异常称为受查异常

一个方法必须声明所有可能抛出的受查异常,二非受查异常要么不可控制(Error),要么就应该避免发生(RuntimeException)。如果方法没有声明所有可能发生的受查异常,编译器就会发出一个错误消息。
注意:如果在子类中覆盖了超类的一个方法,子类方法中声明的受查异常不能比超类方法中声明的异常更通用,也就是说,子类方法中可以抛出更特定的异常,或者根本不抛出任何异常。特别需要说明的是,如果超类方法没有抛出任何受查异常,子类方法也不能抛出任何受查异常,那么这个方法就必须捕获方法代码中出现的每一个受查异常。

在JavaSE7中,同一个catch子句中可以捕获多个异常类型。例如,假设对应缺少文件和未知主机异常的动作是一样的,就可以合并catch子句:

try{
    *code...*
}catch(**FileNotFoundException | UnknowHostException e**){
    *code...*
}catch(Exception){
    *code...*
}

只有当捕获的异常类型彼此之间不存在子类关系时才需要这个特性。(捕获多个异常时,异常变量隐含为final变量,因为不能为变量引用赋不同的值。)

在catch子句中可以抛出一个异常,这样做的目的是改变异常的类型。
基本方法:

try{
    *code...*
}catch(SQLException e){
    throw new ServletException("database error:" + e.getMessage());
}

可以有一个更好的处理方法,并且将原始异常设置为新异常的“原因”:

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

当捕获异常时,就可以使用 Throwable e = se.getCause(); 重新得到原始异常。

*带资源的try语句
资源属于一个实现了AutoCloseable接口的类(Closeable是它的子接口),JavaSE7为以下的代码提供了一个很有用的方式。
假设有以下的代码:

*open a resource*
try{
    *code...*
}finally{
    *close the resource*
    //这里close方法会抛出异常。
}

如果在try语句块中的代码抛出了一些非IOException的异常,这些异常只有这个方法的调用者才能给预处理。执行finally语句块,并调用close方法。而close方法本身也有可能抛出IOException异常。当出现这种情况时,原始的异常将会丢失,转而抛出close方法的异常。
如果想要获取第一个异常,可以有以下的方式解决:

InputStream in = ...;
Exception ex = null;
try{
    try{
        *code...*
    }catch(Exception e){
        ex - e;
        throw ex;
    }
}finally{
    try{
        in.close();
    }catch(Exception e){
        if(ex == null) throw e;
    }
}

而JavaSE7中关闭资源的处理会容易许多:

try(*resource res = ...*){
    *code...*
}

try块退出时,会自动调用res.close()。

//例子
try(Scanner in = new Scanner(new FileInputStream("xxxx"), "UTF-8")){
    while(in.hasNext())
        System.out.println(in.next());
}

这个块正常退出或存在一个异常时,都会调用in.close()方法,就好像使用了finally块一样(带资源的try语句本身也可以有catch子句和一个finally子句,这些子句会在关闭资源后执行)。
如果try块抛出一个异常,而且close方法也抛出一个异常,原来的异常会重新抛出,而close方法抛出的异常会“被抑制”。被抑制异常将自动捕获并由addSuppressed方法增加到原来的异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值