闲着无聊,抽空看看JAVA视频,作为菜鸟级,这里谈谈异常那些事儿~~
顾明思义:异常就是不正常。异常就是在程序中导致程序中断运行的一种指令流。这个导致程序奔溃的现象,我们就称之为异常。
程序中异常的处理逻辑:
JVM虚拟机执行指令出错的时候,会创建一个异常对象,同时将这个异常抛给调用者Main()方法。Main()方法接收到异常后发现程序员没处理,直接抛给JVM虚拟机,JVM收到发现错误没人处理,直接中断程序并给出提示。
那么怎么在这个过程中拦截这个错误,不让他抛给JVM呢? 这个拦截操作,对于我们程序员来说,叫做捕获异常。
看一段代码,看看它有什么问题。
从代码上看貌似没问题,逻辑都正常。但是实际还是会有很多问题。比如,我输入不是数字,或者除数为0,这都会产生异常。
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);
}
比如我在控制台,输入一串"字符串",提示报错如下:
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,报错如下:
Exception in thread "main" java.lang.ArithmeticException: / by zero//除法异常错误
我输入这样的参数,程序就报错了,那如何处理这些异常,让程序能执行下去呢?
程序员捕获异常的过程,我们用try...catch...,大家可以把这个try相当于if,catch相当于方法体中的执行的内容,表示如何处理。
大概的意思就是,如果发生了错误,执行catch的部分。catch中定义如何消除这个问题。
Try -catch的格式,如下:
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中定义错误处理方法,如下:
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也可以合并成一个,可以按照下面的方式进行处理
catch (ArithmeticException| InputMismatchException e) //多异常格式第2种
由于上面的Arithme和InputMismatch都是运行时异常的子类,我们也可以这样定义:
catch (RuntimeException e){
System.out.println("您的输入有误~~,请检查您的输入");
}
再来看看Finally. 还是上面的静态方法。
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()方法重新选择.如下:
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抛出异常,也就是不处理异常,让调用者后续处理。如果后续调用者不处理,那么异常就会给JVM,JVM就会中断程序。这个是没有任何触发点。
异常是否抛出去,应该站在哪个角度思考? 如果因为传参导致异常,应该通过throws将异常抛出去。随后有调用者接着处理,实际生产中灵活搭配。
所以,异常的处理办法就是:扔出去交给别人处理,或者现在你自己就处理。
好的, 本期,就分享到这里。下次我们继续分析其他有意思的Key.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。