当前位置: 主页 > JAVA语言

java异常类层次结构图-java 枚举类 异常参数

发布时间:2023-02-08 22:19   浏览次数:次   作者:佚名

1 概述

Java代码中的异常处理是一个非常重要的部分。 从代码中可以看出其使用已经与业务逻辑紧密结合。 部分业务逻辑还是由异常来完成,更多的时候是处理异常。 可以改善逻辑,避免可能的错误,避免小错误造成的大停顿。

在一般的项目中,运行时异常会被定制以满足项目的需要。 可以捕获或不捕获此类异常。 它们不会导致整个系统挂掉,但在很多情况下,没有被捕获和处理就会导致业务出错。

这里我们模拟几种情况,指出什么时候使用异常捕获。

2、情况分析

先看没有任何处理的代码

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7

8}9

10 公共静态 voidinvoke(){11 System.out.println("---11---");12 int i = 1/0;13 System.out.println("---12---") ;14 }15 }

其执行结果如下:

---1---

---11---线程“main”中的异常java.lang.ArithmeticException:/为零

在 com.donghao.test1.ExceptionTests01.invoke(ExceptionTests01.java:14)

在 com.donghao.test1.ExceptionTests01.main(ExceptionTests01.java:7)

分析:main方法调用invoke方法,执行到第12行出错,导致算法异常。 此时,由于没有异常处理方法,结果是程序执行到这里就直接中断了,执行结果中输出的异常堆栈信息是Java内部默认的异常处理机制的结果。

修改一:我们在invoke方法内部添加异常捕获机制,代码如下:

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7

8}9

10 public static voidinvoke(){11 try{12 System.out.println("---11---");13 int i = 1/0;14 }catch(Exception e){15 System.out.println ("---12---");16 }17 System.out.println("---13---");18 }19 }

java异常类层次结构图_层次聚类算法 java_java 枚举类 异常参数

结果:

---1---

---11---

---12---

---13---

---2---

结果分析:我们在invoke方法的执行代码周围添加异常捕获代码来捕获Exception,它是所有异常的基类,当然这里也包括算法异常,那么这个捕获机制会捕获1/产生的异常0 捕获到这个异常后,会跳转到catch语句块执行这个异常的处理语句。 执行完成后,会继续执行try...catch语句块之后的代码。 这样做的好处是显而易见的。 一个小错误不会妨碍整个代码的继续执行。 当然,如果是比较严重的问题,我们确实需要暂停执行,所以不能使用这种情况。 只是用前面的代码,所以异常处理机制的执行时机完全根据项目的业务情况而定,非常灵活,不是一成不变的。 根据实际业务场景合理使用。

改造2:我们在main方法中也加入了异常捕获

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 try{5 System.out.println("---1---");6 invoke();7 }catch(Exception e){8 System.out. println("---2---");9 }10 System.out.println("---3---");11 }12

13 public static voidinvoke(){14 try{15 System.out.println("---11---");16 int i = 1/0;17 }catch(Exception e){18 System.out.println ("---12---");19 }20 System.out.println("---13---");21 }22 }

其执行结果如下:

---1---

---11---

---12---

---13---

---3---

结果和之前几乎一模一样。 不同的是2没有输出。 一是我把2的输出位置改了,加上了3的输出,现在3相当于之前2的位置。 2之所以没有输出是因为Any exception只能被捕获一次。 一旦被捕获并处理,以后就不会再被捕获。 即使我在main方法中把异常类型改成算法异常,也不会被捕获java异常类层次结构图,只会捕获离它最近的异常。 包含异常的异常捕获,这里的两次异常捕获其实是嵌套的异常捕获,两者捕获的异常还是一致的。 一般情况下,我们不会使用这个,因为它没有意义。 但不代表它完全不会出现。 可能invoke里面的代码比较长,会出现多个异常。 我们可以在main方法中捕获,invoke中的异常捕获只是针对单个异常,说明该异常的发生不会影响invoke方法后面代码的执行。 一旦没有异常捕获的代码发生异常,就会中断后面所有代码的执行(在同一个代码块中)。 这个异常会被main方法中的异常捕获机制捕获并执行。 处理,使得main方法中调用invoke之后的代码仍然可以执行,不会因为调用导致的异常而中断。

但是如果我们把invoke方法中的异常捕获改成如下:

1 个公共类异常测试 01 {2

java 枚举类 异常参数_java异常类层次结构图_层次聚类算法 java

3 public static voidmain(String[] args) {4 try{5 System.out.println("---1---");6 invoke();7 }catch(Exception e){8 System.out. println("---2---");9 }10 System.out.println("---3---");11 }12

13 public static voidinvoke(){14 try{15 System.out.println("---11---");16 int i = 1/0;17 }catch(NullPointerException e){18 System.out.println ("---12---");19 }20 System.out.println("---13---");21 }22 }

执行结果发生了变化:

---1---

---11---

---2---

---3---

为什么? 正是因为我们更改了invoke方法中捕获的异常类型。 之前是异常基类型Exception,现在改为具体的空指针异常。 那么这个异常捕获只能捕获到空指针异常。 它对此处发生的算法异常没有影响。 会视而不见(由于错误的异常类型,那么这个异常捕获就相当于没有加法,可以想象成没有异常捕获的情况),这样会导致invoke方法中的所有代码在1/0之后发生的异常不会被执行。 ,但是我们在main方法中新增的异常捕获可以捕获这个算法异常,所以12和13不会输出,而是在异常发生后直接跳转到main方法捕获异常,并执行catch语句块处理语句输出 2,然后是 3。

看一个特例:

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7 }8

9 public static voidinvoke(){10 for(int i = -2;i < 3;i++){11 System.out.println("---11---");12 System.out.println("12 /"+i+"="+12/i";13 System.out.println("---12---");14 }15 System.out.println("---13---") ;16 }17 }

invoke 方法是一个循环输出。 当第 12 行发生异常时,循环被中断。 默认异常处理机制打印异常堆栈:

---1---

---11---

12/-2=-6

---12---

---11---

12/-1=-12

---12---

java异常类层次结构图_层次聚类算法 java_java 枚举类 异常参数

---11---线程“main”中的异常java.lang.ArithmeticException:/为零

在 com.donghao.test1.ExceptionTests01.invoke(ExceptionTests01.java:14)

在 com.donghao.test1.ExceptionTests01.main(ExceptionTests01.java:7)

修改一:在invoke方法的for循环外添加try...catch:

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7 }8

9 public static voidinvoke(){10 try{11 for(int i = -2;i < 3;i++){12 System.out.println("---11---");13 System.out.println ("12/"+i+"="+12/i);14 System.out.println("---12---");15 }16 System.out.println("---13-- -");17 }catch(异常 e){18 System.out.println("---14---");19 }20 System.out.println("---15---"); 21}22}

结果:

---1---

---11---

12/-2=-6

---12---

---11---

12/-1=-12

---12---

---11---

---14---

---15---

---2---

查看结果,发现循环还是中断了。 当i=0时,第13行产生异常,然后循环中断,然后异常会被for循环外的异常捕获。 这种场景在实际项目中也会出现。 但这种情况很少见。 具体场景是为循环捕获异常。 一旦循环中的某个循环出现异常,整个循环就会终止,异常就会被处理。

java异常类层次结构图_java 枚举类 异常参数_层次聚类算法 java

改造 2:在循环体中添加一个 try...catch 块

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7 }8

9 public static voidinvoke(){10 for(int i = -2;i < 3;i++){11 try{12 System.out.println("---11---");13 System.out.println ("12/"+i+"="+12/i);14 System.out.println("---12---");15 }catch(Exception e){16 System.out.println(" ---13---");17 }18 System.out.println("---14---");19 }20 System.out.println("---15---"); 21}22}

结果:

---1---

---11---

12/-2=-6

---12---

---14---

---11---

12/-1=-12

---12---

---14---

---11---

---13---

---14---

---11---

12/1=12

---12---

层次聚类算法 java_java异常类层次结构图_java 枚举类 异常参数

---14---

---11---

12/2=6

---12---

---14---

---15---

---2---

这种情况比较常见。 我们将异常捕获内置到for循环内部,只捕获循环体的异常。 这样当某个循环体执行过程中出现异常时,可以私下处理,不影响整个循环的继续进行。 实施。 在循环中,还可以结合continue和break关键字进行更复杂的关系控制,以满足特定的业务需求。

这里我展示一个情况,也是我刚才做的一个业务场景:

1 个公共类异常测试 01 {2

3 public static voidmain(String[] args) {4 System.out.println("---1---");5 invoke();6 System.out.println("---2---" );7 }8

9 public static voidinvoke(){10 for(int i = -2;i < 3;i++){11 try{12 System.out.println("---11---");13 System.out.println ("12/"+i+"="+12/i);14 System.out.println("---12---");15 }catch(Exception e){16 System.out.println(" ---13---");17 继续;18 }19 System.out.println("---14---");20 }21 System.out.println("---15--- ");22 }23 }

你没看错,加一个continue; 控制信息的显示,当异常发生时,执行catch块代码,输出13后,不再执行输出14的操作,直接开始新的循环。

有必要做一个总结:

1- 异常的捕获是有方向的和类型特定的,异常会被离异常发生​​点最近的遏制点或捕获该类型异常的捕获点捕获。 这样我们在做嵌套异常捕获和多重异常捕获的时候,一定要注意把小规模的异常类型放在靠近try块的地方,避免大类型劫持异常,导致你设置的异常类型失败生效。

2- 我们可以通过用 try...catch 包装一段代码,将这段代码与方法体隔离开来,并将其影响降到最低。 即使发生异常,也不会影响后续代码的执行。

3-throw关键字与catch块配合使用,表示捕获到的异常会再次抛出,这里不处理,所以必须在方法调用时再次捕获,才能继续被抛出,但是直到最后一个方法,它必须被处理(显式抛出的异常必须被捕获和处理,无论你抛出多少次)。

三、项目异常处理

异常转换

我们会在项目中自定义异常。 这些例外通常有明确的目的。 我们甚至可以在项目的每个级别定义不同的异常。 这时候就会涉及到异常转换。 其实转换很简单,只要Catch异常java异常类层次结构图,在catch块中捕获一行,重新抛出(throw)一个新的异常,将之前的异常信息e作为新异常的参数即可。

1 try{2 int i = 1/0;3 }catch(Exception e){4 throw newRuntimeException(e);5 }

如上例,第2行会抛出一个异常,该异常会被catch块捕获,然后在内部进行消化,重新抛出一个RuntimeException,并将原来的异常信息作为新异常的异常信息(即保持原来的异常消息)。