Java基础语法之异常

2024-01-08 19:12:48

异常的概念

在Java中,将程序执行过程中发生的不正常行为称为异常(Exception)

异常与错误的区别

错误是程序无法处理的,如OutofMemoryError(内存溢出),StackOverFlowError(栈溢出错误),VirtualMachineError(Java虚拟机运行错误)……

异常是程序本身可以处理的,可以向上抛出或捕获处理

异常的体系结构

1.Throwable类:是异常体系的顶层类,其派生出俩个重要的子类Error和Exception

2.Error类:是Java虚拟机无法处理的严重问题,比喻JVM的内部错误,资源耗尽等,一旦发生回力乏术

3.Exception类:此异常产生后程序员可以通过代码进行处理,使程序继续执行。我们平时所说的异常就是Exception

异常的分类

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

1.运行时异常

是RuntimeException类及其子类(NullPointerException空指针异常,ArrayIndexOutOfBoundException数组越界异常,ArithmeticException算数异常),是程序运行阶段发生的异常,也称为非受查异常,是程序已经通过编译得到字节码文件后再由JVM执行时出现的异常

2.编译时异常

编译期间的异常,从语法上讲是必须处理的异常,如果不处理,程序就不能编译通过,也称为受查异常

异常的处理

1.try catch关键字

try后面是可能出现异常的代码,catch是想要捕捉的异常

当不用try catch时,JVM会自动处理异常,即直接终止程序运行,如下

而当用trycatch处理后,则如下:

2.出现异常直到异常处理之间的代码不会执行

没有打印haha

3.当catch中想要捕捉的异常与抛出的异常不一致时,异常就会交给JVM处理,即终断程序运行

4.异常信息的打印

System.out.println(e.getMessage());//只打印异常信息

System.out.println(e);//打印 异常类型:异常信息

e.printStackTrace(); //打印信息最全面

先看前俩种打印方式:

再看最后一种打印方式:

但当把catch中的语句调换顺序后:

发现异常信息竟然在程序最后执行了

这是因为printStackTrace()方法是使用其他方法执行的,而不是单纯用println,所以会有时间延迟

5.可以写多个catch,捕捉到哪个算哪个

也可以写到一个catch里面

6.一次只可能抛出一个异常

因为一旦抛出异常,异常后面的代码就不会执行,直到将异常解决

7.如果一场之间有父子关系,一定是子类异常在前一个catch,父类异常在后一个catch

如果写反了,就会如下报错:

8.可以通过一个catch捕获所有类型的异常

这个就是异常的父类:Exception类

但不建议这样写,能详细些就详细些

异常的抛出

1.程序编译或运行时自动抛出

就是上面提到的代码

2.程序员主动抛出异常

throw关键字

如下代码

因为我们没有解决此异常,所以交给了JVM处理,即把程序终止了

那如何自己处理呢?还是用try catch,可以在test1函数中处理,也可以在test1函数的调用者main函数里面处理,如下:

或者:

以上是针对抛出运行时异常的,那如果是编译时异常呢,就没有这么简单了

throws关键字

编译时异常一旦出现就会导致编译不通过,就没法在运行时进行处理,这时就要用到throws关键字来声明异常,如下:

处理还是和上面一样

但当是在test1函数中处理异常时,main函数后面也要声明此异常,否则会报错:

下面是对的:

总结

1.当直接抛出Exception这个父类时,默认是受查异常,也就是说必须惊醒throws声明
2.当一个方法中可能出现多个受查异常时,需要throws多个异常

3.当抛出的异常有父子关系时,秩序声明父类异常

4.既然有无throws关键字,方法都可以自己处理异常,那为什么还要抛出给调用者处理异常

在一个项目中,某个方法可能被多个方法调用,当用来throws关键字后,就可以提醒调用者自己去处理异常,这时的处理方法就可以根据调用者的意愿来进行,但要是同意让方法自己处理,那处理方式就会单一,

5.什么时候调用者也要用到throws关键字

如果调用者不想去处理异常,就也要在后面通过throws去声明异常,然后交给jvm处理

finally关键字

finally块中的代码,不管前面是否抛出或捕获异常,它里面的代码都会被执行到,如下

作用

在写程序时,有些特定的代码,不论是否发生异常都需要被执行到,比如程序中打开的资源必须要在程序正常或异常退出之前关闭。但因为异常引发的跳转可能使某些代码无法执行,这时finally就起作用了:

比如Scanner资源的关闭:

结果如下,当我键入的不是int型数据时,就会抛出异常,但finally中还可以正常执行,并将scanner资源关闭

但是发现,finally后面的代码一样可以执行到,那为什么还要有finally?

看下面的例子:写一个函数,返回一个输入的数据>>:

当我们正常输入整形数据时,会在try中直接执行return语句,导致if语句执行不到,导致资源的浪费,而只有输入非整形数据时才能正常关闭。这种情况下就要用到finally关键字:

注意

1.一般不建议在finally中写return语句

如下代码,当我们键入10时,main函数中接收到的是10吗?不是

结果接收到的是100.

自定义异常

用这个例子改写一个异常

如何自定义异常类

先来看程序提供的异常:

都继承了Exception类,并且有俩个构造方法,我们模拟它来自定义UserNameException和PassWordException,这属于运行时异常,最好是继承RuntimeException

如何使用呢?如下:

当自定义的异常继承了Exception类时,默认是受查异常

此时在方法后面要声明异常,可以向上抛出到调用者让调用者处理,也可以自己处理,如果是自己处理,那调用者也要声明异常

文章来源:https://blog.csdn.net/zyh20050430/article/details/135449746
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。