前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单聊聊JAVA中的异常<Exception>

简单聊聊JAVA中的异常<Exception>

原创
作者头像
南非骆驼说大数据
修改2021-04-11 11:19:49
8140
修改2021-04-11 11:19:49
举报
文章被收录于专栏:南非骆驼说大数据

前言|

闲着无聊,抽空看看JAVA视频,作为菜鸟级,这里谈谈异常那些事儿~~

一、什么是异常?

顾明思义:异常就是不正常。异常就是在程序中导致程序中断运行的一种指令流。这个导致程序奔溃的现象,我们就称之为异常。

程序中异常的处理逻辑

JVM虚拟机执行指令出错的时候,会创建一个异常对象,同时将这个异常抛给调用者Main()方法。Main()方法接收到异常后发现程序员没处理,直接抛给JVM虚拟机,JVM收到发现错误没人处理,直接中断程序并给出提示。

那么怎么在这个过程中拦截这个错误,不让他抛给JVM呢? 这个拦截操作,对于我们程序员来说,叫做捕获异常

二、异常引出

看一段代码,看看它有什么问题。

从代码上看貌似没问题,逻辑都正常。但是实际还是会有很多问题。比如,我输入不是数字,或者除数为0,这都会产生异常。

代码语言:javascript
复制
public class Demo1{
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字");
        int x = input.nextInt();
        System.out.println("请再输入一个数字");
        int y = input.nextInt();
        System.out.println(x/y);
    }

比如我在控制台,输入一串"字符串",提示报错如下:

代码语言:javascript
复制
Exception in thread "main" java.util.InputMismatchException   //输入异常提示
	at java.base/java.util.Scanner.throwFor(Scanner.java:939)
	at java.base/java.util.Scanner.next(Scanner.java:1594)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2212)

或者除数输入为0,报错如下:

代码语言:javascript
复制
Exception in thread "main" java.lang.ArithmeticException: / by zero//除法异常错误

我输入这样的参数,程序就报错了,那如何处理这些异常,让程序能执行下去呢?

三、捕获并处理异常

程序员捕获异常的过程,我们用try...catch...,大家可以把这个try相当于if,catch相当于方法体中的执行的内容,表示如何处理。

大概的意思就是,如果发生了错误,执行catch的部分。catch中定义如何消除这个问题。

Try -catch的格式,如下:

代码语言:javascript
复制
try{
// 有可能发生异常的代码段
}catch(异常类型1 对象名1){
// 异常的处理操作
}catch(异常类型2 对象名2){
//异常处理操作
} ...
finally{
// 异常的统一出口
}

这里要讲到finally必然执行的异常统一处理出口 ,无论程序是否发生异常,finally必然执行。因此,我们在实际生产中,会把必须要执行的代码参数统一放到这个选项。因为这部分内容必然执行。

四、异常体系结构

异常指的是Exception , Exception类, 在Java中存在一个父类Throwable(可能的抛出)

Throwable存在两个子类:

1.Error:表示的是错误,是JVM发出的错误操作,只能尽量避免,无法用代码处理。

2.Exception:一般表示所有程序中的错误,所以一般在程序中将进行try…catch的处理。

大概的思路图如下:

异常结构图
异常结构图

我们可以这样理解,非受检异常如果代码有问题,是不会报错的。只有在执行的时候才会出问题。而受检异常必须处理完异常后,程序才能往后执行。RuntimeException都是非受检异常。除RuntimeEx类之外的左右异常类都是受检异常类。是需要明确修改的。

五、处理异常

再次回到上面的代码,当我们在执行代码的时候,用户输入0或者字符串的时候,报错了。程序进行不下去,我们就可以使用Try..catch的方式来进行处理。代码如下:

我们重新定义一个静态方法haha,将有问题的代码放入Try中,Catch中定义错误处理方法,如下:

代码语言:javascript
复制
private static void haha(){
        try {
            Scanner input = new Scanner(System.in);
            System.out.println("请输入一个数字");
            int x = input.nextInt();
            System.out.println("请再输入一个数字");
            int y = input.nextInt();
            System.out.println(x/y);
        }catch (InputMismatchException e){
            System.out.println("亲,必须输入数字啊");
        }catch (ArithmeticException e){
            System.out.println("除数不能为0啊,帅哥");
        }
    }

这个时候,我们在主方法中,再次调用这个方法的时候,输入的错误就能被正常处理,程序也就不会中断执行了。那么这就是最简单的多异常处理过程。

当然另个catch也可以合并成一个,可以按照下面的方式进行处理

代码语言:javascript
复制
catch (ArithmeticException| InputMismatchException e)  //多异常格式第2种

由于上面的Arithme和InputMismatch都是运行时异常的子类,我们也可以这样定义:

代码语言:javascript
复制
catch (RuntimeException e){
            System.out.println("您的输入有误~~,请检查您的输入");
     }

再来看看Finally. 还是上面的静态方法。

代码语言:javascript
复制
private static void haha(){
        try {
            Scanner input = new Scanner(System.in);
            System.out.println("请输入一个数字");
            int x = input.nextInt();
            System.out.println("请再输入一个数字");
            int y = input.nextInt();
            System.out.println(x/y);
            System.out.println("处理完毕");
        }catch (RuntimeException e){//多态,扩大异常的查询范围
            System.out.println("您的输入有误~~,请检查您的输入");
        }finally {
            //必然执行的异常统一处理出口
            //无论是否发生异常,finally必然执行。
            System.out.println("程序执行完毕,下次再来使用吧");
        }

    }
}

我们再次在主方法调用haha()方法,发现:无论输入错误的0或是字符串,Finally部分一定会执行。如下:

那么以上就是异常发现、到异常处理的这么一个整体的过程。

六、案列实践

用户选号使用某机器功能,须在0~3数字间选择,如果选择错误,则提示用户输入错误,重新选择,程序不中断。

定义一个菜单,方法为menu(),然后方法如果用户输入错误,则递归提示用户重新输入。如果输入错误,则捕获异常,同时递归Menu()方法重新选择.如下:

代码语言:javascript
复制
public static  int menu(){
        System.out.println("请根据提示,选择功能序号:");
        System.out.println("1. 增加XX");
        System.out.println("2. 删除XX");
        System.out.println("3. 修改XX");
        System.out.println("0. 退出");

        Scanner input = new Scanner(System.in);
        int num = -1;
        try {
            num = input.nextInt();
            if(num<0 || num>3){
                System.out.println("功能序号必须是:0/1/2/3");
                return menu();//递归
            }
            return num;
        }catch (InputMismatchException e){
            System.out.println("哈哈,程序出错了,必须输入数字额~~");
            return menu();

        }

    }
}

那么程序一执行,发现异常后,程序不会中断,会再次提示用户重新输入,直到正确的出来,才结束流程。因此就是捕获异常,处理异常,整个流程。

七、抛出异常-throws

throws抛出异常,也就是不处理异常,让调用者后续处理。如果后续调用者不处理,那么异常就会给JVM,JVM就会中断程序。这个是没有任何触发点。

异常是否抛出去,应该站在哪个角度思考? 如果因为传参导致异常,应该通过throws将异常抛出去。随后有调用者接着处理,实际生产中灵活搭配。

所以,异常的处理办法就是:扔出去交给别人处理,或者现在你自己就处理。

好的, 本期,就分享到这里。下次我们继续分析其他有意思的Key.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言|
  • 一、什么是异常?
  • 二、异常引出
  • 三、捕获并处理异常
  • 四、异常体系结构
  • 五、处理异常
  • 六、案列实践
  • 七、抛出异常-throws
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档