概述的内容理解就好,对应应用层的内容需要掌握

异常概述

  • 异常:非正常情况。

什么是异常?其实就是非正常情况,通俗的说,异常就是咱程序出现了错误。 Java中的 异常是一个很庞大的体系,要求你知道他的体系结构划分

异常 Throwable 分类

异常 - 图1

可以通过上图看到,对应Java体系中异常分为2大类:一个是异常(Exception),还有一个是错误(Error)。下面我们来分别看一下这两个内容和区别。

异常 Exception

第一个就是Exception,程序代码层级我们可以处理的异常内容。

  • 合理的应用程序可能需要捕获的问题「可预料的问题」

比如NullPointerException空指针异常,你要是通过null常量调用成员方法,程序就会报空指针异常。

解决方案:就是在调用成员方法的时候加上判断,不让null调成员方法就可以了。

异常的处理方式

我们既然知道这个解决的思路了,下面我们就来看下在开发的代码中怎么处理这些异常。
有2种方式:一种呢就是业务逻辑代码自己捕获这个异常,然后自己处理;还有一种就是业务逻辑代码把这个异常抛出来,谁调用谁处理。

JVM默认的异常处理方式

我们前面代码出现问题,在代码层级我们都没有处理,只是JVM自己默认处理的。
JVM的默认处理方式就是将异常的信息打印到控制台上,然后终止程序,这就是为什么以前的代码出现报错信息,对应的代码就不会再继续往下执行的原因。

  • 在控制台打印错误信息,并终止程序

我们需要处理的异常是Exception,如果我们不处理,那就由JVM来默认处理的,JVM处理的方式就是将异常信息打印到控制台显示出来并终止程序。

下面我们来看一个正常的代码块内容:

  1. int a = 13;
  2. System.out.println(a);

我们看到上面的内容可以正常打印输出,那这个时候我加上一些东西。

我们知道对应的被除数在数学里是不可以为0的,那我这里就让它除以0,看一下效果:

  1. //被除数0
  2. int b = 13/0;
  3. System.out.println(b);

对应控制台显示异常信息:

  1. Exception in thread "main" java.lang.ArithmeticException: / by zero
  2. at top.testeru.keywords.tryp.Test.main(Test.java:22)
  • 控制台打印异常信息解释说明
    • ArithmeticException:异常类型
    • by zero:异常原因
    • Test.java:22:包名.类名.方法 哪一行出现的错误

可以看到JVM处理的结果是在控制台显示报错信息,并且终止程序执行,因为我们看到后面的打印输出内容没有在控制台进行一个打印。

try…catch「finally」
  • 捕获,自己处理

首先,我们来看第一个。就是自己捕获异常自己处理,用到的代码是:try--catch-finally

(一)格式

  1. try {
  2. //尝试执行的代码
  3. }catch (Exception exception){
  4. //Exception 异常类型
  5. //... 出现可能异常之后的处理代码
  6. }finally {
  7. //里面的代码一定会执行,主要做资源回收关闭操作
  8. }

(二)应用

我们下面对上面报错代码进行一个try-catch异常处理,通过try-cath来处理异常。

  1. try {
  2. //尝试要执行的代码
  3. int b = 13/0;
  4. System.out.println(b);
  5. }catch (Exception e){
  6. //出现问题后的代码(解决方案)
  7. System.out.println("被除数不能是0");
  8. }
  9. System.out.println("----最后打印内容----");
  1. 被除数不能是0
  2. ----最后打印内容----

可以看到对应的最后打印内容输出了,控制台也没有报错了,但是b的值还是没有打印,打印的是:catch里面的内容「被除数不能为0」

(三)特点

  • 处理完异常之后程序是会继续执行

(四)finally作用

  • 正常情况下,无论怎样finally代码块内容都会被执行

如果在cath代码里面进行一个return语句,可以看到最后打印的内容没有了。说明执行完cath的内容就直接return了,代码不会再继续运行。

那如果不管是有没有 return我都想要去执行的最后打印内容,怎么解决呢?
就要用到我们前面写的finally,就是无论怎样finally代码块里面的内容都会被执行。

代码如下:

  1. try {
  2. //尝试要执行的代码
  3. int b = 13/0;
  4. System.out.println(b);
  5. }catch (Exception e){
  6. //出现问题后的代码(解决方案)
  7. System.out.println("被除数不能是0");
  8. return;
  9. }finally {
  10. System.out.println("----最后打印内容----");
  11. }

上面是对应catch代码块添加return效果,那如果代码不抛出异常,try代码块的内容return的时候,finally代码块的内容会被执行吗?
其实是一样的,无论是try-catch里面谁return,对应finally的代码块都会被执行。对应demo如下:

  1. try {
  2. //尝试要执行的代码
  3. int b = 13;
  4. System.out.println(b);
  5. return;
  6. }catch (Exception e){
  7. //出现问题后的代码(解决方案)
  8. System.out.println("被除数不能是0");
  9. return;
  10. }finally {
  11. System.out.println("----最后打印内容----");
  12. }

以上就是加不加finally代码块的区别;即使try--catch里面有returnfinally里面的代码在正常情况下都会被执行。

finally正常情况下一定会执行,那什么是非正常情况呢?

比如说正在执行的过程中,服务器突然断电了,那这就是非正常情况了,这种情况不管是什么代码都不会被执行了。

(五)执行流程

先执行try里面的内容,看看有没有问题。如果没有异常直接执行finally有代码块中的内容 ,如果有问题,在报错的那行就会跳转到cath代码块中执行里面的内容,再执行finall代码块中的内容

  • 执行try代码块
    • 有异常:try代码块{异常代码}—->cath代码块—->finall代码块
    • 无异常:try代码块—->finall代码块

throws
  • 抛出,交给调用者处理

其实就是直接在方法后面加上throw并抛出异常就可以。
首先定义一个方法,方法内

(一)格式

  1. 访问权限 返回值 方法名(形参) throws Exception{
  2. }

(二)应用
还是对上面报错的代码进行一个throws异常处理。

  1. public class Test {
  2. //抛出异常,交给调用者处理
  3. public static void num() throws Exception{
  4. int c = 13/0;
  5. System.out.println("c:"+c);
  6. }
  7. public static void main(String[] args) throws Exception {
  8. num();// throws Exception
  9. //main函数直接抛出异常,对应的main函数异常抛给了JVM,因为main函数是JVM调用的
  10. System.out.println("看看都执行了吗");
  11. }
  12. }
  1. Exception in thread "main" java.lang.ArithmeticException: / by zero
  2. at top.testeru.keywords.tryp.Test.num(Test.java:57)
  3. at top.testeru.keywords.tryp.Test.main(Test.java:48)

可以看到对应的最后打印内容没有输出,控制台有报错了,main方法直接抛出异常给了JVM,让JVM进行的异常操作

(三)特点

  • 执行结束后,程序不再继续执行

(四)调用者处理异常方式

同样调用者处理方法抛出异常方式有2种,一种就是上面我们演示的,直接在调用函数上抛异常,一层层的抛出,最后还是JVM去执行。
还有一种就是上面演示的第一种,在调用函数种把被调的方法使用try-catch进行异常的抛出。这样,try-cath抛出异常后程序会继续执行。

错误 Error

异常还有另外一个分类,就是Error。

  • 合理的应用程序不应该试图捕获的问题「不可预料的问题」

当然程序如果出现了Error的错误,我们也解决不了。比如StackOverFlowError内存溢出,
这个异常和代码没关系,代码都是正常,只是服务器的硬件上你的内存不够用了,就会报这个异常。

解决方案,就是添加内存就可以了。
或者比如说服务器宕机、数据库崩溃,在登录页面对应就是访问不了,这些是Java程序员无法预料到的问题

总结

1.异常的概念
2.异常的分类