首页 > 编程语言 >JAVA之异常处理

JAVA之异常处理

时间:2024-02-06 14:34:14浏览次数:32  
标签:JAVA 处理 方法 try finally catch 异常

一、异常的体系结构

image

  • Throwable:是java中所有异常和错误的父类,其包括两个子类Error(错误)和Exception(异常)。
    • Error:是程序中无法处理的错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等。这类错误无法恢复或捕获,将会导致应用程秀中断。此类异常发生时,必须手动解决。
    • Exception:是程序可以捕获并可以处理的异常。主要分为运行时异常(不受检异常)和受检异常。
      • RuntimeException:是运行时异常,也是不受检异常。此类异常一般是由程序逻辑错误引起的,为编译器不要求强制处理的异常,可以选择处理解决,也可以不处理。
      • 非运行时异常(受检异常):指Exception中除RuntimeException及其子类之外的异常。编译器会检查此类异常,若检查出来则必须解决处理,要么用try-catch捕获处理,要么用throw将异常交给方法的调用者处理,否则编译不通过。

二、异常的处理方法

2.1 try - catch - finally处理

  • try:通常在try{}中放可能出现异常的业务逻辑代码。如果try代码块中发生异常,则会生成一个异常类的对象,会与catch()中的异常类进行匹配,匹配成功就会被catch捕获然后运行catch中的代码;匹配不成功则程序终止。
  • catch:通常用来捕获try{}中发生的异常,并放置异常处理代码。如果处理完成后,没有finally{}则退出try-catch结构;存在finally{},则去执行finally{}中的代码。
    • catch多个异常类型的时候, 会从上到下进行捕获,上面捕获成功后下面的不会再捕获。如果有子父类关系,小的范围写上面而大的范围写下面; 如果没有子父类关系,谁在上谁在下无所谓。
    • 可以在catch块中访问异常对象的相关信息,通过访问catch块的后异常形参的相应方法来获得
getMessage():返回该异常信息的跟踪栈信息输出到标准错误输出

printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。

printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流。

getStackTrace():返回该异常的跟踪栈信息。
  • finally:finally{}一般放置资源回收的代码,用于回收在try块里打开的物理资源(如数据库连接、网络连接和磁盘文件)。不管try块中的代码是否出现异常,也不管哪一个catch块被执行,甚至在try块或catch块中执行了return语句,finally块总会被执行。
    • 只有finally块执行完成之后,才会回来执行try或者catch块中的return或者throw语句。如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
try{
  //业务实现代码
  ...
}catch(SubException e){
  //异常处理块
  ...
}catch(SubException e2){
   //异常处理块
   ...
}finally{
   //资源回收
   ...
}

2.2 throws + 异常类型

throws 一般用于当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理。如果方法的上一级无法解决就会再将异常向上抛出, 最终会抛给main方法。这样一来main方法中调用了这个方法的时候,就需要解决这个可能出现的异常。当然main方法也可以不解决异常, 将异常往上抛出给JVM,JVM对异常的处理方法是,打印异常的跟踪栈信息,并中止程序运行。如果java虚拟机也无法解决的话,那么JVM就over了。

注意:子类重写的方法抛出的异常类型不能大于父类被重写的方法抛出的异常类型,否则会catch不到子类重写的方法抛出的异常。

2.3 合理使用try - catch - finally和throws + 异常类型

  • 如果父类中被重写的方法没有用throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用tyr-catch-finally方式处理。
  • 执行的方法中,先后又调用了另外的几个方法,这几个方法是递进关系执行的,建议这几个方法使用throws的方式处理,而执行的方法使用try-catch-finally方式进行处理。

三、查看异常堆栈信息

public class Test {
                                        
    public static void fun1() {
        fun2();
    }

    public static void fun2() {
        fun3();
    }

    public static void fun3() {
        try {
            fun4();
        } catch (Exception e) {
            throw new RuntimeException("fun3",e);
        }
    }

    public static void fun4() {
        throw new RuntimeException("fun4");
    }

    public static void main(String[] args) {
        fun1();
    }
}

image

既然是异常堆栈,那肯定是FILO(先进后出)的。调用顺序为main->fun1->fun2->fun3->fun4。第一部分的java.lang.RuntimeException是在fun3中抛出的,所以第一部分异常堆栈信息为fun3->fun2->fun1->main。

又因为但是fun3中抛出的异常中传入了一个cause,用于设置抛出该异常的原因。所以就有了第二部分的Caused by,这个打印的是fun3中捕获的异常的栈信息。而fun4中抛出的异常的栈信息前半部分与第一部分异常栈重合,所以printStackTrace()方法省略了这部分的打印。

image
异常堆栈信息总结

  • 异常栈信息的第一行就是抛出这个异常的最原始的位置,最后一行就是最开始调用的地方。
  • 如果异常栈信息后面跟着Cause by,就证明抛出当前异常的原因是捕获到了下面的异常。
  • 快速分析异常信息,首先查看异常栈信息最开始的那一行了解异常的类型,再找到最开始调用的位置进行定位,结合Cause by分析发生异常的根本原因,最后在定位的位置进行调试修改。

参考资料:https://www.cnblogs.com/brokyz/p/14672500.html#42-throws--%E5%BC%82%E5%B8%B8%E7%B1%BB%E5%9E%8B
https://www.cnblogs.com/wugongzi/p/11858228.html
https://blog.csdn.net/tianjindong0804/article/details/105117779

标签:JAVA,处理,方法,try,finally,catch,异常
From: https://www.cnblogs.com/Aying216/p/18009221

相关文章

  • JavaScript的正则表达式
    目录一、概念二、修饰符1.g(global,全局)2.i(ignorecase,不区分大小写)3.m(multi-line,多行)4.s(single-line,单行)5.u(Unicode,Unicode字符)6.y(sticky,粘性)三、元字符1..(匹配非换行符\n的任意一个字符)2.\d(匹配数字)3.\D(匹配除数字以外的所有字符)......
  • Java学习初体验
    1.安装JDK进入官网:https://oracle.com->Products->Java->DownloadJava选择JDK版本,再选择相应操作系统,注意CPU架构为X86还是ARM,安装即可。ps:下载JDK版本要下载TLS版本,LTS(Long-TermSupport,长期支持)是指针对软件的某一版本,提供长时间的技术支持、安全更新和错误......
  • JavaScript移动端的手指触摸touch事件
    目录概念touchstart触摸发生事件touchend触摸结束事件touchmove触摸移动事件touchcancel触摸取消事件自定义事件自定义轻触事件方法touchtap自定义左右划动事件方法touchswiper概念在JavaScript中,移动端基本的手指触摸touch事件有四种,分别为:touchstart:手指触摸屏幕时......
  • JavaScript函数柯里化
    目录概念函数柯里化的实现函数柯里化简写函数柯里化使用案例函数柯里化工厂函数概念函数柯里化就是给一个函数传入一部分参数,此时就会返回一个函数来接收剩余的参数。使用场景:递归使用和处理函数,函数功能尽可能单一。函数柯里化的实现//没有柯里化的实现function......
  • java实现导出mysql数据库表信息
    java实现导出mysql数据库表信息,导出信息包含:数据库用户名,表英文名,表中文名,表业务描述,字段数量等等packagesrc.main.biz.ucenter.utils;importorg.apache.poi.ss.usermodel.Row;importorg.apache.poi.ss.usermodel.Sheet;importorg.apache.poi.ss.usermodel.Workbook;impor......
  • 解密JavaChassis3:易扩展的多种注册中心支持
    本文分享自华为云社区《JavaChassis3技术解密:易扩展的多种注册中心支持》,作者:liubao68。JavaChassis的早期版本依赖于ServiceCenter,提供了很多差异化的竞争力:接口级别转发。通过注册中心管理微服务的每个版本的元数据,特别是契约数据。结合契约数据,能够实现版本级别的路由......
  • 深入浅出Java多线程(九):synchronized与锁
    引言大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第九篇内容:synchronized与锁。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!!在现代软件开发中,多线程技术是提升系统性能和并发能力的关键手段之一。Java作为主流的编程语言,其内置的多线程机制为开发者......
  • Java中的 << , >> , 和 >>>所代表的含义
    Java中的<<,>>,和>>>所代表的含义标题Java中的<<,>>,和>>>所代表的含义1.<<表示左移运算符例如8<<1,表示将8向左移1位,低位补0,结果为16。例如8<<2,表示将8向左移2位,低位补0,结果为32。左移一位相当于乘以二二进制演算:8的二进制:1000向左移动两位结果为100000,换......
  • 【转帖】解决Java/MySQL性能问题的思路
    plantegg.github.io/2023/08/28/解决问题思路/ 10年前写的,重新发一下系统性能问题CPU(基本上WEB服务器没有多少IO,主要是CPU有瓶颈)top/vmstat观察CPU使用率,Load负载,r/b线程数量等;IO(数据库大多数时候瓶颈是IO,主要是索引没建好;如果数据库CPU紧张的话,检查一下是不是orderb......
  • JAVA对象的成员方法
    方法介绍使用方法的好处......