8-Java基础:异常处理

一、概述

  1. 异常: 在Java语言中,将程序中发生的不正常情况称为“异常”(开发过程中的语法错误和逻辑错误不是异常)

  2. 异常(广义)分类:
      1. Error: Java虚拟机无法解决的严重问题,如:JVM系统内部错误、资源耗尽等严重情况(栈溢出-StackOverFlowError;内存溢出-Out of Memory,OOM),一般不编写针对性的代码进行处理
      2. Exception(狭义异常):其他因编程错误或偶然的外在因素导致的一般性问题,如空指针访问、试图读取不存在的文件、网络连接中断、数组角标越界,可以使用针对性的代码进行处理

  3. 错误解决方式:
       1. 遇到错误就终止程序的运行
       2. 程序员在编写程序时,就考虑到错误的监测、错误消息的提示,以及错误的处理

  4. 错误捕获:
    *捕获错误最理想的是在编译 期间,但有的错误只有在运行时才会发生,如除数为0,数组下标越界等
    从而,存在 编译时异常 / 受检checked异常——Javac.exe 和 运行时异常 / 非受检unchecked 异常——java.exe

  5. 异常体系结构:
    在这里插入图片描述

二、异常处理机制

问题: 编写程序时,经常要在可能出现错误的地方加上检测的代码,一般会使用 i f if if判断,但过多的 i f − e l s e if-else ifelse判断会导致程序的代码加长、臃肿,可读性差
解决: 采用异常处理机制

Java异常处理:java的异常处理机制是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护

异常的处理: 抓抛模型
   1. 过程一:"抛”:程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象——一旦抛出对象以后,其后的代码就不再执行

异常对象的产生:①系统自动生成的异常对象②手动生成一个异常对象并抛出( t h r o w throw throw

   2. 过程二:“抓”:异常的处理方式:① t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally;② t h r o w s throws throws

t h r o w throw throw t h r o w s throws throws 的区别:

t h r o w throw throw 表示抛出一个异常类的对象,生成一个异常对象;声明在方法体内
t h r o w s throws throws 属于异常处理的一种方式;声明在方法的声明处

2.1 try-catch-finally

try{
	//可能出现异常的代码	
}catch(异常类型1 变量名1){
	//处理异常的方式1
}catch(异常类型2 变量名2){
	//处理异常的方式2
}
...
finally{
	//一定会执行的代码
}

说明:
   1. f i n a l l y finally finally 可选

   2. 使用 t r y try try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,然后根据此对象的类型去 c a t c h catch catch中进行匹配

   3. 一旦 t r y try try中的异常对象匹配到某一个 c a t c h catch catch时,就进入 c a t c h catch catch中进行异常处理,一旦处理完成,就跳出当前的 t r y − c a t c h try-catch trycatch(没有 f i n a l l y finally finally) 的结构,继续执行后面的代码

   4. c a t c h catch catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓;若满足子父类关系,则要求子类一定声明在父类的上面,否则报错

   5. 常用的异常对象处理方式:① S t r i n g g e t M e s s a g e ( ) String \quad getMessage() StringgetMessage() ; ② p r i n t S t a c k T r a c e ( ) printStackTrace() printStackTrace()

   6. 在try结构中声明的变量,出了try结构以后,就不能再被调用了

   7. t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally结构可以嵌套

try-catch-finally中的finally使用:
  1. f i n a l l y finally finally 可选

  2. f i n a l l y finally finally 中声明的代码一定会被执行, 即使catch中又出现异常了,或者try中有return语句,或者catch中有return语句等情况

  3. 像数据库连接、输入输出流、网络编程Socket等资源,JVM无法自动回收,需要手动进行资源释放,此时的资源释放,就可以声明在finally中

在这里插入图片描述
注: finally中的fis.close:
  1. 要考虑将fis的定义放在try-catch-fianlly外面;
  2. 要考虑JVM不会自动释放fis资源,需要手动释放,所以放在finally中;
  3. 要考虑当file没有创建成功时,fis就可能为空,进行资源释放时需要先判断是否为空,否则可能出现空指针异常;
  4. 要考虑fisde 类型为输入流,可能出现IOException

s u m m a r y \bold{summary} summary😗
   1. 使用 t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally处理编译时异常,使得程序在编译时不再报错,但运行时仍可能报错,相当于使用try-catch-fianlly将一个编译时可能出现的异常,延迟到运行时出现
  2. 开发中,由于运行时异常较为常见,所以通常不针对运行时异常编写try-catch-finally,针对于编译时异常,一定要考虑异常处理

2.2 throws + 异常类型

用法: 写在方法的声明处,指明此方法执行时,可能会抛出的异常类型;一旦当方法体执行时出现异常,仍会在异常代码出生成一个异常类的对象, 此对象满足 t h r o w s throws throws后异常类型时,就会被抛出;异常代码后续的代码就不再执行

注:
   1. t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally:将真正的异常给处理掉了
   2. t h r o w s throws throws的方式只是将异常抛给了方法的调用者,并没有真正将异常处理掉——>最后的调用者还是得用 t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally进行异常处理

2.3 一些注意点

  1. 方法重写的规则之一: 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型——这样,在使用多态过程中,如果子类出现异常,就可以被父类对象给 c a t c h catch catch
    在这里插入图片描述2. 开发中如何选择使用 t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally还是 t h r o w s throws throws?
       1. 如果父类中被重写的方法没有 t h r o w s throws throws方式处理异常,则子类重写的方法也不能使用 t h r o w s throws throws,意味着如果子类重写的方法中有异常,必须使用 t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally方式处理
       2. 执行的方法A中,先后又调用了另外的几个方法,这几个方法是递进关系执行的【下一个方法使用了上一个方法得到的值】,建议这几个方法使用 t h r o w s throws throws的方法进行处理,而方法A可以考虑使用 t r y − c a t c h − f i n a l l y try-catch-finally trycatchfinally方式进行处理——保证一遇到方法就中断下面的方法执行
       3.

三、手动抛出异常——throw

异常对象的产生:①系统自动生成的异常对象②手动生成一个异常对象并抛出( t h r o w throw throw

public class StudentTest {
    public static void main(String[] args) {
        try {
            Student s = new Student();
            s.regist(-2);
            System.out.println(s);
        } catch (Exception e) {
//            throw new RuntimeException(e);
            System.out.println(e.getMessage());
        }

    }
}
class Student{
    int id;

    public void regist(int id) throws Exception {
        if(id> 0){
            this.id = id;
        }else{
//            System.out.println("您输入的数据非法");
            //手动抛出异常对象
//            throw new RuntimeException("您输入的数据非法");
            throw new Exception("您输入的数据非法");//包括编译+运行时异常,需要处理
        }
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                '}';
    }
}

四、用户自定义异常类

如何自定义异常类?【点进某个异常类模仿者写】
   1. 继承于现有的异常结构: R u n t i m e E x c e p t i o n RuntimeException RuntimeException E x c e p t i o n Exception Exception
   2. 提供全局常量 s e r i a l V e r s i o n U I D serialVersionUID serialVersionUID
   3. 提供重载的构造器

public class RuntimeException extends Exception {
    static final long serialVersionUID = -7034897190745766939L;//序列号
    public RuntimeException() {//构造器1
        super();
    }

    public RuntimeException(String message) {//构造器2
        super(message);
    }
    public RuntimeException(String message, Throwable cause) {//构造器3
        super(message, cause);
    }
    public RuntimeException(Throwable cause) {//构造器4
        super(cause);
    }
    protected RuntimeException(String message, Throwable cause,
                               boolean enableSuppression,
                               boolean writableStackTrace) {//构造器5
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

明前大奏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值