异常速通(java)

前言

我个人学 异常的时候还是卡了一下的,重新看了两遍视频才懂,可能我笨吧,如果没有基础建议先看视频再结合博客,我相信总能学会的

异常概述

异常也是个类,在顶层是 Throwable 类,然后 有 Error 类 和 Exception 类继承了 Throwable类,Error 就是 JVM 虚拟机无法解决的问题,程序会直接崩溃,所以 Error 我们不用去管他,而 Exception 是可以用代码解决的错误。

在这里插入图片描述

这里我们主要关注 Exception , Exception 分为运行时异常 和 编译时异常,运行时异常就是指 RuntimeException 下的异常,编译时异常就是Exception 子类中除了 RuntimeException 其他的所有异常



运行时异常

编译器不强制要求处理的异常,因为运行时异常会自动 throws 到调用者,这里不知道 throws 没关系,后面就知道了。

常见的运行时异常

  • 空指针异常 (NullPointerException)

当某个对象为 null, 你直接访问

  • 数组越界异常 (ArraylndexOutOfBoundsException)

这个大家都很熟悉了,这里不解释了

  • 类型转换异常 ( ClassCastException)

试图将对象转化成不是实例的子类,例如你向上转型完,你再转成一个毫不相关的对象

  • 数字运算异常(ArithmeticException)

出现异常的运算:例如 整数 / 0

  • 数字格式不正确异常(NumberFormatException)

将字符串转换成一种数值类型,但该字符串不能转化为适当格式:例如 “123” 转 123 ,你搞个 “abc”,它就转不了数值类型


编译时异常

必须要处理的异常,否则代码不给过,只要知道这点就好了

最重要的点就是运行时异常可以不处理,编译时异常一定要处理



异常处理的方式

运行时异常 如果没处理 会自动 throws 出去
编译时异常,程序必须处理,try-catch-finally 或者 throws

.

try-catch-finally

程序员在代码中捕获发生的异常,自行处理

try {
	捕获到异常创建一个异常对象,传给 catch 括号的异常对象
} catch (Exception e) {
	得到这个异常对象,然后程序员就可以自己处理了
} finally {
	不管有没有异常发生,始终都要执行 finally 里的内容
    通常我们将 释放资源 的代码,放在 finally
}

如果没有捕获到异常 catch 代码块不会执行

如果没有 finally 语法也可以通过


细节
1. 如果异常发生了,则 try 异常块后面发生的代码不会指定,直接进入 catch 块


try {
   int a = 10, int b = 0; 
   int c = a / b; //这里抛出了异常
   System.out.println("异常发生后,try 块异常后的代码不会执行了"); //这句不会执行了
} catch (RuntimeException e) {
   System.out.println("异常发生了");
} finally {
   System.out.println("不管怎么样这个都执行");
}

2. 可以有多个catch语句,捕获不同的异常,要求父类异常放在后面,比如 Exception 要在 NullpointerException后面,如果发生异常,只会匹配一个catch,因为 try 发生异常后代码不执行的

int a = 10;
int b = 0;

int[] arr = new int[3];

try {
    
  
	System.out.println(arr[4]); //这里抛出异常了,寻找下面匹配的 catch ,然后try块中下面的代码不执行了,直接 finally 完就没了
	int c = a / b;
	System.out.println("异常发生后,try 块异常后的代码不会执行了");
    
} catch(ArithmeticException e) {
    System.out.println("发生了 除数为 0 异常");
} catch (RuntimeException e) { //Runtime 是 Arithmetic 的父类所以要放在下面
    System.out.println("异常发生了");
} finally {
    System.out.println("不管怎么样这个都执行");
}

System.out.println(arr[4]);这里这里的时候可以理解为 throw new ArithmeticException() 然后丢到 catch 里

是 throw 不是 throws 区别后面说


3. 可以进行 try - finally 配合使用,这种用法相当于,没有捕获异常,因此程序会直接崩掉,用于执行一段代码,不管发生异常,都必须执行某个业务逻辑

try {
   int a = 10;
   int b = 0;
   int c = a / b;
   System.out.println("异常发生后,try 块异常后的代码不会执行了"); //这句不会执行了
} finally {
   System.out.println("不管怎么样这个都执行");//finally执行之后直接崩了,因为运行时异常没处理,默认 throws 了
}


throws

将发生的异常抛出,交给调用着(方法)来处理,最顶级的处理者时JVM
如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,就应该显示地抛出去

细节

  1. 在方法声明中用 throws 语句可以声明抛出异常的列表,throws 后面的异常类型可以是方法中产生的异常类型,也可以时它的父类。
public class Main {
    public static void main(String[] args) throws Exception{
        f1();
    }

    //这里就是用了列表
    public static void f1() throws FileNotFoundException,Exception{
        //创建了一个文件流对象
        //这里的异常时一个编译异常
        //1.使用 try-catch-finally 处理
        //2.使用 throws,直接抛出异常,让调用者解决
        FileInputStream fis = new FileInputStream("d://test.txt");
    }
}

这里有一个编译异常必须要处理,我选择直接 throws 到调用者,但是调用者不想用 try catch 处理 又throws 到 JVM ,JVM 直接寄掉


2. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型

class Father {
    public void method() throws RuntimeException {
        
    }
}

class Son extends Father {
    //这里重写了父类方法,抛出的异常的类型,必须和父类一致,或者父类异常的子类型
    @Override
    public void method() throws NullPointerException {

    }
}


自定义异常

  1. 如果继承 Exception,属于编译异常(如果用 Excpetion 要注意它一定要被处理
  2. 运行时异常我们直接继承 RuntimeExcptionn
public class Main {
    public static void main(String[] args) {

        int age = 180;

        if( age < 0 || age > 120 ) {
            throw new AgeException("年龄要大于 0 ,小于 120");
        }
        System.out.println("你的年龄范围正确");
    }
}

//自定义异常
class AgeException extends RuntimeException {
    public AgeException(String message) {
        super(message); //message 一直传到 Throwable 的 detailMessage,然后输出detailMessage
    }

    public AgeException() {
        super();
    }
}

这里是 throw 不是 throws

一般情况下,自定义异常继承 RuntimeException,好处是我们可以使用默认的处理,就是 RunmtimeException 自动向上抛

至于异常为什么这么定义,可以随便弄一个异常然后追一下源码,就懂了



throw 和 throws

throw 和 throws 的区别

意义位置后面跟的东西
throws异常处理的一种方式方法声明处异常类型
throw手动生成异常对象的关键字方法体中异常对象

Throwable的常见成员方法

方法名称说明
public String getmMessage()返回此 throwable 的详细消息字符串
public String toString()返回此可抛出的简短描述
public void printStackTrace()把异常的错误信息输出在控制台
  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值