异常(JAVA笔记第三十二期 )
p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解
目录
- 异常体系
- 编译时异常
- 运行时异常
- 异常的作用
- 异常的处理方式
- 捕获异常(自己处理异常)
- 捕获异常注意事项
- 异常常用方法
- 抛出异常处理
- 抛出和捕获的区别
- finally关键字
- 综合练习
- 自定义异常
异常体系
异常,即程序初出现的问题。
学习异常,可以让我们以后在程序出现异常的时候知道该怎么处理
编译时异常即其他异常
编译时异常
编译时异常,,在编译阶段,必须手动处理,否则代码报错
//编译时异常String time = "2024年11月5日";SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");Date date = sdf.parse(time);System.out.println(date);
运行时异常
//运行时异常int []arr = {1,2,3,4,5};System.out.println(arr[10]);
异常的作用
作用一:异常是用来查询bug的关键参考信息
作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况
比如下面这种。当给出的年龄超出范围时会抛出异常
public void setAge(int age){if (age<18||age>40){//超出范围抛出运行时异常throw new RuntimeException();}else {this age = age;}}
异常的处理方式
第一种:JVM默认的处理方式
- 把异常的名称,异常的原因以及异常出现的位置信息输出在了控制台
程序停止运行,异常下面的代码不会再运行了第二种:捕获异常(自己处理)
- .
第三种:交给调用者处理,即抛出异常
- .
捕获异常(自己处理异常)
格式
try {可能出现异常的代码}catch (异常类名 变量名){异常的处理代码;}
目的:当代码出现异常的时候。可以让程序继续往下执行
可以选中可能出现异常的代码使用ztrl+ait+t,用try/catch一键进行包围
举例
int []arr = {1,2,3,4,5};try {System.out.println(arr[10]);//此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象//拿着这个对象与catch中的对象进行对比,看括号中的变量是否能接收这个对象//如果能接收,表示该异常被捕获(抓住),执行catch里面对应的代码//执行完毕后继续执行下面的其他代码}catch (ArrayIndexOutOfBoundsException e){//出现异常时的处理方法System.out.println("索引越界");}System.out.println("测试");
捕获异常注意事项
如果try 中没有遇到异常的话
会把try 里面的代码执行完毕,不会执行catch里面的代码。
只有当捕获了异常才会执行catch里面的代码
如果try 中遇到了多个异常
- 两种情况
.
当可以被捕获的异常在无法被捕获的异常上方,则会一直执行到可以被捕获的异常,然后转到执行catch里面的代码,不会执行可以被捕获的异常下方的代码
.
当无法被捕获的异常在可以被捕获的异常上方,则会按照JVM默认的处理方式进行处理解决方法:写多个catch语句来捕获异常
注意:如果要捕获的多个异常之间存在父子关系的话,那么父类一定要写在子类的下面,否则会报错;
并且只要捕获了一个异常,那么其下方的异常就不会被捕获了(因为不会被执行)
举例
int []arr = {1,2,3,4,5};try {System.out.println(1/0);System.out.println(arr[10]);}catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException e){System.out.println("索引越界");}catch (ArithmeticException e){System.out.println("算数异常");}System.out.println("测试");
如果try 中遇到的异常没有被捕获,则会按照JVM默认的处理方式进行处理
如果try 中遇到了异常,不管有没有捕获异常,异常下面的代码就不会执行了
异常常用方法
在catch语句中使用
注意:printStackTrace()方法只是打印错误信息,并没有停止虚拟机
抛出异常处理
核心:告诉调用者出错了
一般都写在方法里
在方法中出现了异常的时,该方法就没有在继续执行下去的意义了,
这时采用抛出处理,让该方法结束运行并告诉调用者出现了问题
其有两个关键字:throws、throw
throws写在方法定义处,表示声明一个异常
格式
public void 方法名() throws 异常类名1,异常类名2······ {方法体;}
注意:编译时异常:必须要写;
运行时异常:可以不写
而thorw写在方法里面,可结束方法
是手动抛出异常对象,交给调用者
其下面的代码不会再执行了
格式
```java
public void 方法名() {throw new ArrayIndexOutOfBoundsException();}
举例
import java.text.ParseException;public class Demo1 {public static void main(String[] args) throws ParseException {int []arr = {1,2,3,4,5};try {int arr0 = getArr(arr);} catch (NullPointerException e) {System.out.println("空指针异常");}catch (ArrayIndexOutOfBoundsException e){System.out.println("索引越界异常");}System.out.println("测试");}public static int getArr(int []arr) throws RuntimeException{if (arr==null){//手动创建一个异常对象,并把这个异常对象交给方法的调用处//此时方法就会结束,下面的代码就不会再执行了throw new NullPointerException();//并且throw下面无法再写代码了}if (arr.length==0){//手动创建一个异常对象,并把这个异常对象交给方法的调用处//此时方法就会结束,下面的代码就不会再执行了throw new ArrayIndexOutOfBoundsException();//并且throw下面无法再写代码了}return arr[0];}}
抛出和捕获的区别
抛出的核心:告诉调用者出错了
一般都写在方法里
.
捕获的核心:不让程序停止
一般都写在方法调用处
finally关键字
finally的使用请看大佬讲解
综合练习
import java.util.Scanner;public class Demo2 {/*键盘录入学生的姓名和年龄姓名的长度在3-10之间超出这个范围是异常数据不能赋值,需要重新录入,直到录入正确为止注意:需要考虑用户在键盘录入时的所有情况比如:录入年龄时超出范围,录入年龄时录入了abc等情况*/public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while (true) {try {System.out.println("请输入姓名");String name = scanner.nextLine();checkName(name);System.out.println("请输入年龄");int age = Integer.parseInt(scanner.nextLine());checkAge(age);//如果所有的数据都是正确的,那么跳出循环System.out.println("年龄"+name);System.out.println("姓名"+age);break;} catch (NumberFormatException e) {System.out.println("年龄格式有误");continue;}catch (RuntimeException e) {System.out.println("姓名的长度或年龄的范围有误");continue;}}System.out.println("录入成功!");}public static String checkName(String str)throws RuntimeException{if (str.length()<3||str.length()>10){throw new RuntimeException();}return str;}public static int checkAge(int n)throws RuntimeException{if (n<18||n>40){throw new RuntimeException();}return n;}
}
自定义异常
意义:让控制台的报错信息更加见名知意
步骤
- 定义异常类
- 写继承关系
- 空参构造
- 带参构造
举例
public class NameFormatException extends RuntimeException{//NameFormat:当前异常的名字:表示姓名格式化问题//Exception:表示当前类是一个异常类//写继承关系//运行时:RuntimeException。 核心:表示由于参数错误而导致的问题//编译时:Exception。 核心:提示程序员检查本地信息public NameFormatException() {}public NameFormatException(String message) {super(message);}}