首页 > 编程语言 >一次对Java异常机制的理解

一次对Java异常机制的理解

时间:2022-11-24 00:23:09浏览次数:44  
标签:main Java try 理解 catch 机制 doProcess 异常 循环

一次对Java异常机制的理解

近期有一个对接三方接口的任务,在这个过程中用到了许多 try-catch 处理,发现自己对异常处理是一知半解,浅浅研究了一下,记录一下,也帮助小伙伴如何正确使用 try-catch 达到预期的结果。

写在前面

java的异常处理机制,用得好,可以达到预期的效果,用得不好,反而会降低JVM的性能

  1. try-catch代码段会产生额外的性能开销
  2. java每实例化一个Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。

所以结论是:能不用则不用,如要用,尽量使 try 块的代码尽可能的少

1、循环中发生异常,导致循环中断

我现在有一个任务,需要循环去处理,代码如下:

public static void main(String[] args) throws Exception {
    try {
        // 处理任务
        doProcess();
    } catch (RuntimeException e) {
        e.printStackTrace();
    }
}


public static void doProcess() {
    for (int i = 0; i < 30; i++) {
        if (i % 10 == 0) {
            throw new RuntimeException("Invalid number");
        } else {
            System.out.println(i);
        }
    }
}

我的预期是:当 i = 0,10,20 的时候抛出异常,其余情况打印 i 的值

实际结果:程序直接抛出异常就结束了

后来查了相关资料,发生异常的时候,JVM会把异常往上抛,doProcess方法不能处理这个异常,就抛到了 main 方法中,刚好 main方法能够处理,但是处理完之后,当前的栈帧已经来到了 main线程,也就是说,当异常抛出了 doProcess 方法之后,相当于这个方法已经执行完了。

后续经过改造,来到了version 2.0:

public static void main(String[] args) throws Exception {
    // 处理任务
    doProcess();
}


public static void doProcess() {
    try {
        for (int i = 0; i < 100; i++) {
            if (i % 10 == 0) {
                throw new RuntimeException("Invalid number");
            } else {
                System.out.println(i);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我的预期是:当 i = 0,10,20 的时候抛出异常,其余情况打印 i 的值

实际结果:程序直接抛出异常就结束了

经过分析,发生异常时,JVM还是会把异常往上抛,被 for循环外try 块捕获了,但是为什么还是没能满足我们的预期,理由还是同上,在循环中发生异常,循环中无法捕获这个异常时,就会继续往上抛,一旦抛出了循环外,标志循环也结束了

继续改造 version 3.0

public static void main(String[] args) throws Exception {
    // 处理任务
    doProcess();
}


public static void doProcess() {

    for (int i = 0; i < 100; i++) {
        try {
            if (i % 10 == 0) {
                throw new RuntimeException("Invalid number");
            } else {
                System.out.println(i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

这次程序能满足我的预期了,在循环中发生异常,但是在循环中被捕获了,并没有跳出循环,所以循环还在继续。

通过这次对异常处理的思考,一定要尽可能小的去使用 try-catch,一是能保证代码的正确性,二是能保证jvm的性能。

标签:main,Java,try,理解,catch,机制,doProcess,异常,循环
From: https://www.cnblogs.com/Fzeng/p/16920601.html

相关文章

  • JavaScript 面向对象(五)原型链
     5.原型链prototype原型'每一个构造函数都有一个属性叫做prototype,指向一个对象,'当这个构造函数被new的时候,它的每一个实例(即将生成的对象)的__proto__属性,也指向......
  • JavaScript 面向对象(番外)JS字面量
    javascript字面量在JavaScript里面,字面量包括:字符串字面量(stringliteral)、数组字面量(arrayliteral)和对象字面量(objectliteral),另外还有函数字面量(function......
  • JavaScript 面向对象(一)对象
    字面量’字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量。字面量分为字符串字面量(stringliteral)、数组字面量(arrayliteral)和对......
  • JavaScript--href调用JS方法和href="#"与href="javascript:void(0)"
    关于href属性<a>标签的href属性用于指定超链接目标的URL。超链接的URL可能的值:绝对URL-指向另一个站点(比如href="http://www.example.com/index.htm")相......
  • JavaScript 面向对象 番外笔记
    小笔记JS输出空格解决方法:1、使用输出html标签 document.write("&nbsp;&nbsp;"+"1"+"&nbsp;&nbsp;&nbsp;&nbsp;"+"23");结果:1232、使用CSS样式document.w......
  • JavaScript 面向对象(番外)JS原始类型和引用类型
    书摘来自异步社区《JavaScript面向对象精要》一书中的第1章,第1.1节第1章原始类型和引用类型大多数开发者在使用Java或C#等基于类的语言的过程中学会了面向对象编程。由......
  • JavaScript 面向对象 番外 Object.defineProperty()
     注意,如果描述符中的某些属性被省略,会使用以下默认规则: ......
  • java中的注解
    一、Spring中的常见注解。1、声明Bean的注解。@Component:该注解是一个泛化概念,仅仅表示一个组件对象(Bean),没有明确的角色。@Repository:该注解用于数据访问层(DAO)的类......
  • java8新特性
    什么是函数式(Functional)接口只包含一个抽象方法的接口,称为函数式接口。你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么......
  • java-IO流之字符流
    字符流由于字节流操作中文不是特别的方便,所以Java就提供字符流字符流=字节流+编码表中文的字节存储方式用字节流复制文本文件时,文本文件也会有中文,但是没有问......