Java—异常

  • 抛出异常—throw

  • Java处理异常的语法

    • 异常声明—throws
  • 异常捕获—try…catch

    • try 负责回收资源
  • 向上传递,处理异常

  • 处理流程

  • throw 和 throws 的区别:

  • 自定义异常类

什么是异常?


在程序的运行或者编译时,所产生的错误统称为异常 (也叫Bug)

异常的存在形式


异常在java中以类的形式存在,每一个异常类都可以创建异常对象

我们平时看到的异常,都被封装成一个类

例如:0 为除数,异常为:ArithmeticException

查看在线文档会发现:

在这里插入图片描述

Java异常体系


在这里插入图片描述

异常的分类


异常分为:运行时异常 和 编译时异常

运行时异常

运行时异常又称为:非受查异常,指的是在程序运行时所抛出的异常

特点:Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过

编译时异常

编译时异常又称为:受查异常,在程序编译时的异常

是RuntimeException以外的异常,类型上都属于Exception类及其子类,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过

错误 Error

是程序无法处理的错误,表示运行应用程序中较严重问题,是Java虚拟机无法解决的问题

常见 Error:StackOverflowError 和 OutOfMemoryError

错误是预测不到的,如果应用程序出现了Error,那么将无法恢复,只能重新启动应用程序

编译时异常和运行时异常的区别

| | 编译时异常 | 运行时异常 |

| — | — | — |

| 发生概率 | 比较高 | 比较低 |

| 处理方式 | 需要在运行之前对其进行 预处理 | 没必要提前进行预处理 |

常见的异常


我们之前已经接触了一些异常,常见的异常还是有必要记住的

  • 0为除数(算数异常)

int a = 10 / 0;

在这里插入图片描述

  • 数组下标越界(数组下标越界异常)

int[] array = {1,2,3};

System.out.println(array[4]);

在这里插入图片描述

  • 访问 null(空指针异常)

空指针异常出现的概率非常高!!

int[] array = {1,2,3};

array = null;

System.out.println(array[2]);

在这里插入图片描述

防御式编程


程序出现问题的时候及时通知程序猿,主要有两种主要的方式:

BYBL

Look Before You Leap,在操作之前就做充分的检查

举例:一个男孩子很喜欢一个女孩子,想要拉女孩子的手,提前问:我可以拉你的手嘛?

EAFP

It’s Easier to Ask Forgiveness than Permission,“事后获取原谅比事前获取许可更容易”,也就是先操作,遇到问题再处理

举例:男孩子先拉的女孩子的手,女孩子很生气,呼了一巴掌,男孩子再回来巴拉巴拉道歉

异常的核心就是EAFP

抛出异常—throw


在Java中,使用 throw 关键字,抛出一个指定的异常对象,将错误信息告知给调用者

举例:

public static int findDate(int[] array,int index){

if(array == null){

throw new NullPointerException(“array为空”);

}

if(index < 0 || index >= array.length){

throw new ArrayIndexOutOfBoundsException(“下标index越界!”);

}

return array[index];

}

注意事项:

  • throw必须写在方法体的内部

在这里插入图片描述

  • 抛出的对象必须是 Exception 或者 Exception 的子类

在这里插入图片描述

在这里插入图片描述

  • 如果抛出的是编译时异常,用户必须处理,否则无法通过编译

在这里插入图片描述

  • 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理

  • 异常一旦抛出,其后的代码就不会执行

Java处理异常的语法


异常声明—throws

指编程人员主动抛出一个异常

任何Java代码都可以抛出异常,在方法声明的位置上使用 throws 关键字,抛给方法的调用者来处理,这种处理异常的态度:上报

举例:

public static void testThrows() throws NullPointerException {

Integer p = null;

System.out.println(p + 1);

}

注意:

  • 方法的调用者负责处理该异常

  • 在定义方法时,把异常抛出就是为了提醒方法的使用者,有异常需要预处理

  • 如果异常对象是 非RuntimeException,则需要在方法申明时加上该异常的抛出

即需要加上 throws 语句 或者 在方法体内 try catch 处理该异常,否则编译报错

  • 执行到 throw 语句,后面的语句块不再执行

异常捕获—try…catch

这个异常不会上报,自行处理,异常抛到此处为止,不再上抛

try {

//可能出现异常的代码

}

catch (Exception1 e) { //参数:异常的类型 e

//捕获try当中可能出现的异常

}

catch (Exception2 e) { //参数:异常的类型 e

//捕获try当中可能出现的异常

} finally {

}

举例:

int[] array = {2,4,6,8};

try{

System.out.println(array[4]);

}

catch (ArrayIndexOutOfBoundsException e){

System.out.println(“捕获到数组越界异常!”);

}

对比:

在这里插入图片描述

注意:

  • try{ } 包含了可能出现异常的代码

  • catch 可以有一个或多个,catch中是捕获 try 当中可能出现的异常,可以通过 catch 捕获多个异常

  • catch 块当中,一定要捕获相应的异常,如果程序抛出的异常在 catch 块当中不能被捕获,则会交给JVM来处理异常,程序便会异常终止

  • 当 try 中的代码出现异常时,try 里异常之后的代码不会执行,马上会跳转到相应的catch语句块中,如果没有异常便不会跳转

  • 不管是否出现异常,finally{ } 里的代码都执行,finally和catch可以分开使用,但finally必须和try一块使用

  • 不建议直接捕获 Exception 异常,要捕获就捕获具体的

  • 不建议在 finally 中出现 return语句

  • catch 只能处理对应种类的异常

  • finally中的代码一定会执行的,一般在finally中进行一些资源清理的扫尾工作

try 负责回收资源

Scanner scan = new Scanner(System.in);

try{

int n = scan.nextInt();

System.out.println(10/n);

}

catch (ArithmeticException e){

e.printStackTrace();

}

finally {

scan.close();

}

在Idea里,会发现 try 背景色会加深,将鼠标放在 try,按 Alt + Enter

在这里插入图片描述

在这里插入图片描述

出现上图,回车即可!

然后代码就会自动被优化:

在这里插入图片描述

即:将 Scan 对象在 try( )中创建,就能保证在 try 执行完毕后自动调用 Scanner 的 close 方法

向上传递,处理异常

先看代码:

public static void func(){

int[] array = {2,4,6,8};

System.out.println(array[4]);

}

public static void main(String[] args) {

func();

}

上述代码,func 方法里存在数组越界异常,但并没有处理,到 main 中调用 func 方法,由于 main方法里也没有处理该异常,则会交给 JVM,那么程序一运行,遇到异常,直接就会终止

改进:

public static void func(){

int[] array = {2,4,6,8};

System.out.println(array[4]);

}

public static void main(String[] args) {

try {

func();

}

catch (ArrayIndexOutOfBoundsException e){

e.printStackTrace();

}

finally {

System.out.println(“hahaha”);

}

异常的传递是可以沿着栈向上传递的,方法是要在栈上开辟内存的

处理流程
  1. 程序先执行 try 中的代码

  2. 若 try 中的代码出现异常,就会结束 try 中的代码,看和 catch 中的异常类型是否匹配

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值