Java异常机制入门详解​
  93byl95AX42O 2023年12月05日 21 0

Java异常机制入门详解

基础知识

什么是异常?

在Java语言中,异常就是代表程序出现的问题。异常的引入不是让我们以后不出异常,而是程序出了异常之后,该如何处理。如如下两段代码,会各抛出一个异常:

int[]arr ={10,20,30};
System.out.println(arr[3]);
ArrayindexOutOfBoundsException

数组索引越界异常

int a =10;
int b =0;
System.out.println(a /b);
ArithmeticException

算数异常

异常的体系

Java异常机制入门详解​_子类


Error异常(严重错误)

Java异常机制入门详解​_运行时异常_02


Error:代表的系统级别错误(属于严重问题)

如果系统一旦出现问题,sun公司会把这些错误封装成Eror对象。Error是给sun公司自己用的,不是给我们程序员用的。因此我们开发人员不用管它。

Exception异常

Java异常机制入门详解​_System_03



Exception:叫做异常,代表程序可能出现的问题。我们通常会用Exception以及他的子类来封装程序出现的问题。异常共有2类:

运行时异常:RuntimeException及其子类,编译阶段不会出现异常提醒。运行时出现的异常(如:数组索引越界异常)

编译时异常:直接继承于Exception类,编译阶段就会出现异常提醒的。(如:日期解析异常)

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

●编译时异常:除了RuntimeExcpetion和他的子类,其他都是编译时异常。编译阶段需要进行处理,作用在于提醒程序员。

●运行时异常:RuntimeException本身和所有子类,都是运行时异常。编译阶段不报错,是程序运行时出现的。一般是由于参数传递错误带来的问题

常见的编译时异常

1.FileNotFoundException

2.ClassNotFoundException

3.SQLException

4.NoSuchFieldException

5.NoSuchMethodException

6.ParseException

常见的运行时异常

1.NullPointerException

2.ArithmeticException

3.ClassCastException

4.ArrayIndexOutOfBoundsException

5.StringIndexOutOfBoundsException

异常的作用

作用一:异常是用来查询bug的关键参考信息

作用二:异常可以作为方法内部的一种特殊返回值以便通知调用者底层的执行情况

小结

1.异常是什么?

●程序中可能出现的问题

2.异常体系的最上层父类是谁?异常分为几类?

●父类:Exception。

●异常分为两类:编译时异常、运行时异常

3.编译时异常和运行时异常的区别?

●编译时异常:没有继承RuntimeExcpetion的异常,直接继承于Excpetion。

编译阶段就会错误提示

●运行时异常:RuntimeException本身和子类。编译阶段没有错误提示,运行时出现的。

异常的处理方式

异常有3中处理方式,分别是:

①JVM默认的处理方式

②自己处理

③抛出异常

JVM默认的处理方式

●把异常的名称,异常原因及异常出现的位置等信息输出在了控制台(以红色字体)

●程序停止执行,下面的代码不会再执行了

public class ExceptionDemo1 {
 public static void main(String[] args) {
 int[] arr = {1, 2, 3, 4, 5};
 System.out.println(arr[5]);

 // 异常后的代码
 System.out.println("看看我执行了吗?");
 }
}

以上代码将会抛出java.lang.ArrayIndexOutOfBoundsException,由于采用的是JVM默认的处理方式,因此在执行输出语句时遇到异常后将停止执行,异常出现后的代码将不会执行。


自己处理(捕获异常)

格式:

try {

可能出现异常的代码;

}catch(异常类名 变量名){

异常的处理代码;

}

目的:当代码出现异常时,可以让程序继续往下执行。

public class ExceptionDemo1 {
 public static void main(String[] args) {
 // 定义一个数组
 int[] arr = {1, 2, 3, 4, 5};
 try {
 // 可能出现异常的代码
 System.out.println(arr[5]); //此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
 // new ArrayIndexOutOfBoundsException();
 //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象
 // 如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码
 // 当catch里面所有的代码执行完毕,继续执行try...catch体系下面的其他代码

 }catch (ArrayIndexOutOfBoundsException e){
 // 如果出现了ArrayIndexOutOfBoundsException异常
 // 要采取的操作
 System.err.println("数组越界!");
 }
 // 异常后的代码
 System.out.println("看看我执行了吗?");
 }
}

关于异常的灵魂四问

灵魂一问:如果try中没有遇到问题,怎么执行?

会把try里面所有的代码全部执行完毕,不会执行catch里面的代码。

注意:只有当出现了异常才会执行catch里面的代码


灵魂二问:如果try中可能会遇到多个问题,怎么执行?

会写多个catch与之对应

细节:

如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面

了解性:

在JDK7之后,我们可以在catch中同时捕获多个异常,中间用竖线|进行隔开表示如果出现了A异常或者B异常的话,采取同一种处理方案,如下:

try {
 // 代码
}catch (ArrayIndexOutOfBoundsException | NullPointerException e){
  System.err.println("出现异常!");
}



灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?

相当于try...catch的代码白写了,最终还是会交给虚拟机进行处理。


灵魂四问:如果try中遇到了问},那么try下面的其他代码还会执行吗?

try语句块下面的代码就不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体,但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理。

Throwable类的常用方法

方法名称

说明

public String getMessage()

返回此throwable的详细消息字符串

public String tostring()

返回此可抛出的简短描述

public voidprintStackTrace()


把异常的错误信息输出在控制台

Idea快捷键Ctrl+Alt+T可以把选中的代码快速包裹进语句块。

方法printStackTrace()打印异常的详细信息,但不会停止程序运行。

抛出处理

关键字throws

写在方法定义处,表示声明一个异常告诉调用者,使用本方法可能会有哪些异常。格式如下:

public void myMethod() throws ArrayIndexOutOfBoundsException, NullPointerException{
 // 方法的代码
}

●编译时异常:必须要写。

●运行时异常:可以不写。


关键字throw

写在方法内,结束方法,表示手动抛出异常对象,交给调用者方法中下面的代码不再执行了

public void myMethod(){
 // 方法的代码
 throw new NullPointerException();
 
}

如下代码:

public class ExceptionDemo3 {
 public static void main(String[] args) {
 int[] arr = {1};
 System.out.println(getMax(arr));
 }

 /**
 * 获取数组中的最大值
 * @param arr 数组
 * @return 最大值
 */
 public static int getMax(int[] arr){

 if (arr == null){
 //手动创建一个异常对象,并把这个异常交给方法的调用者处理
 // 此时方法就会结束,下面的代码不会再执行了
 // 抛出空指针异常
 throw new NullPointerException();
 }else if(arr.length == 0){
 // 抛出越界异常
 throw new ArrayIndexOutOfBoundsException();
 }

 int max = arr[0];
 for (int i = 1; i < arr.length; i++) {
 if (arr[i] > max){
 max = arr[i];
 }
 }
 return max;
 }
}

小结

1.虚拟机默认处理异常的方式

把异常信息以红色字体打印在控制台,并结束程序

2.捕获:try…catch

捕获的主要作用是不让程序停止。

一般用在调用处,能让代码继续往下运行。

3.抛出:throw throws

抛出的主要作用是告诉调用者出错了。

在方法中,出现异常了。方法就没有继续运行下去的意义了,采取抛出处理。让该方法结束运行并告诉调用者出现了问题。

练习

需求:

键盘录入自己心仪的女朋友姓名和年龄。

姓名的长度在3~10之间,

年龄的范围为18-40岁,

超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。

提示:

需要考虑用户在键盘录入时的所有情况。比如:录入年龄时超出范围,录入年龄时录入了abc等情况

import java.util.Scanner;

public class GirlfriendInput {
 public static void main(String[] args) {
 //1.创建键盘录入的对象
 Scanner sc = new Scanner(System.in);
 //2.创建女朋友的对象
 Girlfriend gf = new Girlfriend();
 while (true) {
 //3.接收女朋友的姓名
 try {
 System.out.println("请输入你心仪的女朋友的名字");
 String name = sc.nextLine();
 gf.setName(name);
 //4.接收女朋友的年龄
 System.out.println("请输入你心仪的女朋友的年龄");
 String ageStr = sc.nextLine();
 int age = Integer.parseInt(ageStr);
 gf.setAge(age);
 //如果所有的数据都是正确的,那么跳出循环
 break;
 } catch (NumberFormatException e) {
 System.out.println("年龄的格式有误,请输入数字");
 //continue;
 } catch (RuntimeException e) {
 System.out.println("姓名的长度或者年龄的范围有误");
 //continue;
 }
 }
 //5.打印
 System.out.println(gf);
 }
}

Girlfriend类代码:

public class Girlfriend {
 private String name;

 private int age;

 public Girlfriend() {
 }

 public Girlfriend(String name, int age) {
 this.name = name;
 this.age = age;
 }

 /**
 * 获取
 * @return name
 */
 public String getName() {
 return name;
 }

 /**
 * 设置
 * @param name
 */
 public void setName(String name) {
 int len = name.length();
 if (len < 2 || len > 10){
 // 如果姓名长度不对,则抛出异常
 throw new RuntimeException();
 }
 this.name = name;
 }

 /**
 * 获取
 * @return age
 */
 public int getAge() {
 return age;
 }

 /**
 * 设置
 * @param age
 */
 public void setAge(int age) {
 if (age < 18 || age > 40){
 // 如果年龄不符合要求,抛出异常
 throw new RuntimeException();
 }
 this.age = age;
 }

 public String toString() {
 return "Girlfriend{name = " + name + ", age = " + age + "}";
 }
}


自定义异常

自定义异常的步骤与方法:

①定义异常类,类名要见名知意

写继承关系:运行时异常继承于RuntimeException、编译时异常继承于Exception

③空参构造

④带参构造

意义:就是为了让控制台的报错信息更加的见名

Alt+Insert快捷键快速生成代码块。

上例中,我们可以自定义两个异常,分别用于姓名和年龄输入不符合要求时抛出:

姓名格式不符合要求的异常:

public class NameFormatException extends RuntimeException{
 //技巧:
 //NameFormat:当前异常的名字,表示姓名格式化问题
 //Exception:表示当前类是一个异常类
 //运行时:RuntimeException核心就表示由于参数错误而导致的问题
 //编译时:Exception核心提醒程序员检查本地信息

 // Alt + Insert插入2个构造方法:空参和带参
 public NameFormatException() {
 }

 public NameFormatException(String message) {
 super(message);
 }
}

年龄输入不符合要求时的异常:

public class AgeOutOfBoundsException extends RuntimeException{
 public AgeOutOfBoundsException() {
 }

 public AgeOutOfBoundsException(String message) {
 super(message);
 }
}









【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月05日 0

暂无评论

推荐阅读
93byl95AX42O