Num13_Exception异常


Throwable 类是 Java 语言中所有错误或异常的超类。

常用方法:

  • String getMessage()
    返回此 throwable 的详细消息字符串

  • **void printStackTrace()
    将此 throwable 及其追踪输出至标准错误流。 **

java异常

在这里插入图片描述

java中所有异常的超类Throwable, 其下有两个子类 Error 和 Exception

Error 和 Exception 的区别:

Error

  • Error 是系统级错误,是Java运行环境内部错误或者硬件问题,不能通过程序来处理这样的问题,发生错误时程序退出运行。
  • 它是Java虚拟机抛出的,比如虚拟机内存溢出等。

Exception

  • Exception是程序需要处理的异常,由于程序设计的不完善(程序员逻辑问题)而出现的问题,程序必须进行处理,比如空指针异常,数组下标越界异常等。
  • 通常程序中处理的异常都是Exception

Exception 的分类

1.编译时异常(检查异常)-- CheckedException

java 语言强制要求处理的所有非运行时异常,例如IOException ,SQLException

2.运行时异常(非检查异常 UnChecked) --RuntimeException,

RuntimeException一般是由于程序逻辑错误引起的,比如算术异常,空指针异常等待。

java两种异常处理机制

  • java 中有完善的两种异常处理机制,可以捕获try-catch-[finally] 或者 抛出throws
  • 捕获throws
  • try{
    代码片段;
    }catch(XXXException e){
    处理try中出现的XXXException的代码方案;
    } [finally{}] finally是可选操作,当有finally时,finally中的代码一定会被执行

可以捕获一个超类的异常:
1.当try中出现了几种不同的异常,但是他们的解决办法相同
2.在最后一个catch处理捕获Exception可以避免因为一个未处理的异常导致程序中断。
需要注意的是:多个catch的异常之间若存在继承关系,一定要先捕获子类异常,再捕获超类异常,否则编译不通过。
异常之间没有关系捕获异常时可以随意声明位置

public class Test1_TryCatch {
    public static void main(String[] args) {
        System.out.println("程序开始...");
        try{
            /*
            * 当JVM执行出现错误时,就会实例化对应问题的异常实例,并设置出错位置后将其抛出
            * */
            String str = null;//不初始化的话,直接编译报错:可能未初始化
            str = "";
            str = "abc";
            System.out.println(str.length());//str为null时,不能调用方法和属性,否则报空指针异常。
            System.out.println(str.charAt(2));//str为空串,没有下标为2的字符,报字符串下标越界异常:java.lang.StringIndexOutOfBoundsException
            //报java.lang.NumberFormatException数字格式异常
            System.out.println(Integer.parseInt(str));
            //try语句中报错语句之后的代码都不会执行。
            System.out.println("!!!");
            //当try中代码不出错时,catch不执行。
        }catch(NullPointerException e){
            //定义try中出现空指针异常后的解决办法
            System.out.println("空指针异常");
         //catch 可以定义多个,针对try中不同的异常有不同的处理方式时可以分别捕获并处理
        }catch(StringIndexOutOfBoundsException e){
            System.out.println("字符串下标越界异常");
         /*
         * 通常情况下我们可以捕获一个超类的异常:
         * 1.当try中出现了几种不同的异常,但是他们的解决办法相同
         * 2.在最后一个catch处理捕获Exception可以避免因为一个未处理的异常导致程序中断。
         * 需要注意的是:多个catch的异常之间若存在继承关系,一定要先捕获子类异常,再捕获超类异常,否则编译不通过。
         * 异常之间没有关系捕获异常时可以随意声明位置
         * */
        }catch(Exception e){
            System.out.println("404");
            e.printStackTrace();//打印异常的具体信息
            System.out.println(e.getMessage());//获取出现异常的原因描述:For input string: "abc"
            System.err.println(e.getMessage());//获取出现异常的原因描述:For input string: "abc"(颜色发生变化)
        }
        System.out.println("程序结束!!!");
    }
}

Finally

finally 是try-catch-finally 中的一块,他可以直接跟在try后面(很少这样用),或跟在最后一个catch之后。 finally可以保证只要程序执行到try当中,无论try里面的语句是否抛出异常,finally中的代码必定执行,(除直接退出程序外,如System.eixt(0)则不会执行finally中的代码),通常我们将释放资源这类操作放到finally中,比如IO操作后的关闭。

finally中的语句一定会执行,但是在try中已经将确定要返回的值x是基本类型,即使在finally中值被修改也不改变原先要返回的值。
如果要返回的值是引用类型则finally中改变值,最终返回的值将被改变
当finally中有return语句时,返回finally中的值,
当finally中没有return语句,return语句在finally语句之前,即使finally中对返回的变量值进行修改,也不会改变第一次return中的返回值

return 语句在finally语句之前也要先执行完finally中语句再结束程序,finally语句后的代码不再执行

常见面试题:

请分别说出final ,finally ,finalize(方法名)

final 可以修饰属性,方法,类。
final修饰属性为常量,初始化后不可被修改。
final修饰方法可被继承不能被重写。
final 修饰类不能被继承。

finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带着一个语句块,在系统不发生中断情况下,表示这段语句最终一定被执行,经常被用在需要释放资源,关闭文件,关闭数据库连接的情况下。

finalize是方法名,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。

异常处理机制在IO中的 应用

/**
 * 异常处理机制在IO中的应用
 *
 * @author yyc
 * 2021/9/18 14:33
 */
public class Test3_Finally2 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("fos.txt");
             fos.write(1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if (fos != null) {
                    //如果fos为null,则汇报空指针异常,即没有开流
                    fos.close();//fos的作用域只在try中,要实现finally中顺利关流,所有需要把声明放到try-catch-finally之前。
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

java 处理机制二:Throws

自动关闭特性:AutoCloseable

JDK7之后,推出了一个新特性,AutoCloseable 自动关闭特性

  • 允许我们在IO操作中使用异常处理机制更简洁的完成最后的close()关流操作。
  • 语法:
  • try(定义需要在finally中调用close()方法关闭的对象){
  • IO操作
    
  • }catch(XXXException){
  • ...
    
  • }
  • 上述语法中在try的"()"中定义的并初始化的对象必须实现了java.io.AutoCloseable接口,否则编译不通过,javaIO中的流和
    RandomAccessFile都已经实现了这个接口。

子类重写超类中含有Throws声明异常抛出的方法时对throws的几种特殊的重写规则。

①;子类可以抛出与父类抛出相同异常
②:重写父类的方法也可以不抛出异常
③:子类可以抛出超类方法的部分异常
④:子类可以抛出父类方法抛出的异常的子异常
⑤:子类不能抛出父类中没有抛出的异常
⑥:子类不允许抛出超类方法抛出异常的超类异常(子类抛出的异常不允许大于父类抛出的异常)

throw

throw关键字,用来对外主动抛出的一个异常。
通常以下两种情况,我们主动向外抛出异常:

  • 1.当程序遇到一个满足语法,但是不满足业务要求(逻辑)时,可以抛出一个异常告知调用者。
  • 2.程序执行遇到一个异常,但是该异常类不应当在当前代码片段被解决时可以抛出给调用者。(谁调谁解决)

throw 和 throws 的区别:

  • 1.throw 的声明位置在方法体内,后面跟的是异常类的实例(对象)(new XXXException(”异常信息描述“)),只能有一个;
  • throws 的声明位置在方法声明后,后面跟的是异常类名。
  • 2.throw 后面只能抛出一个异常对象名throws同时抛出多个异常时中间用“,”逗号隔开。
    throw 和 throws 联系:
  • 1.如果方法中有throw 抛出的RuntimeException 及其子类对象,则方法声明上可以没有throws,(由该方法的调用者处理该异常),除此之外,方法声明上必须有throws

当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理这个异常。否则编译不通过,处理方式有两种:
1.在当前方法上继续使用throws声明该异常并抛出给调用者解决。当异常发生在main方法中,我们可以在main方法声明后使用throws抛出该异常,但是main方法是程序的入口,不会再被调用,抛出去之后异常始终得不到处理。所以不建议main方法抛出异常。
2.使用try-catch方式捕获处理。

只有RuntimeException不需要手动抛出异常,其他异常抛出时要在方法上使用throws通知调用者。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值