• 异常处理机制


    1.使用try...catch捕捉异常

    如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,这个异常对象会被提交给Java的运行时环境,把这个过程叫做“抛出异常”

    java的运行时环境受到异常对象后,就会寻找这个异常对象的处理catch语句,如果找到合适的,就把这个异常对象交给catch语句块处理,这个过程被称为“捕获异常” 要是捕获不到异常,运行时环境被终止,退出程序

    无论处在哪里的代码块,只要出现异常,都会产生异常对象。

    2.异常类的继承体系

    try{

    statement1

    statement2

    }

    catch(ExceptionClass1 e1){

    ....

    }

    catch(ExceptionClass2 e2){

    ....

    }

    ...

    每个catch语句里都是处理该异常类及其子类的异常实例

    try语句里面的语句出现异常,生成异常对象,运行时环境接收到异常对象后,以此判断该异常对象是否是catch块后异常类或其子类的实例,如果是,将调用该catch块来处理该异常,不会向下进行,否则再次拿该异常对象和下一个catch块里的异常类进行比较

    try块里声明的变量时代码块内局部变量,它只在try块内有效,在catch块里不能访问该变量。

    异常类的继承树

     Java把所有的非正常情况分为两种:异常(Exception)和错误(Error),他们都继承Throwable 父类

    Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态连接失败等,这种错误无法恢复或不可能捕捉,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图用catch块来捕获Error对象,在定义该方法时,也无需再其throws子句中声明该方法可能跑出Error及其任何子类

    4.多异常捕获

    自从java7开始,一个catch块可以捕获多种类型的异常:

    1.捕获多种类型的异常时,多种异常类型之间用竖线(|)隔开。

    2.捕获多种类型的异常时,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值

    5.访问异常信息

    d当java运行时决定使用某个catch块来处理该异常对象时,会将异常对象赋给catch块后的异常参数。所有的异常对象都包括了几个方法

    getMessage()异常的详细描述字符串

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

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

    getStackTrace() 返回该异常的跟踪栈信息

    6.使用finally回收资源

    有些时候,在try块打开了一些系统物理资源(数据库连接、网络连接、磁盘文件等),这些物理资源必须显示回收

    为了保证一定能回收try块中打开的资源,异常处理机制提供了finally块,finally块一定会被执行,即使前面出现了return语句,如果在异常处理代码中使用了system.exit(1)(关闭虚拟机)语句,那么finally就失去了执行的机会。

    异常处理语句结构里面try是必须的,没有try,就不能有catch和finally,catch和finally至少出现其中之一。

    注意:尽量不要在finally块中使用return或throw等导致方法终止的语句。一旦使用,将会使try、catch里面的return、throw失去意义

    当java程序执行try、catch时遇到了return或者throw,就会找有没有finally语句,如果有,就会执行finally语句里面的,如果finally里面有return或throw,那么方法就会终止,try、catch里面的语句就失去了执行的机会

    7.自动关闭资源的try语句

    为了避免代码的臃肿,java7增强了try语句的功能--允许在try关键字后面紧跟一对括号,括号内可以声明、初始化一个或多个资源(必须显示关闭的).try语句在语句结束后自动关系这些资源。这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口必须实现close()方法。

    8.Checked异常和Runtime异常

    1.RuntimeException类及其子类的实例被称为Runtime异常。

    2.不是RuntimeException类及其子类的实例成为Checked异常(只有java提供)

    java认为Checked异常都是可以被修复的异常,所以必须被显示处理,如果没有处理,编译就会发生错误。

    对Checked的处理方式有两种:

       1)、当前方法明确知道如何处理该异常,程序应该使用try。。。catch语句,在对应的catch块中修复该异常

      2)、当前方法不知道该如何处理这种异常,在定义该方法时声明跑出该异常

    8.1 使用throws声明抛出异常

        使用throws声明抛出异常的思路是,当前方法不知道如果处理这种类型的异常,由上一级调用者处理;如果main方法也不知道如何处理,也使用throws声明抛出异常。这个异常将交给jvm处理。JVM对异常的处理方式是,打印异常的跟踪栈信息,并终止程序的运行。throws声明抛出只能在方法签名中使用,一旦使用了throws抛出了异常,就不需要使用try...catch块来捕获该异常了

    也就是说,如果某段代码调用了一个带throws声明的方法,该方法声明抛出了checked异常,则表明该方法希望它的调用者来处理该异常(调用该方法时要么放在try块里显示捕获该异常,要么放在另一个带throws声明跑出的方法中)子类方法声明跑出的异常不允许比父类方法声明跑出的异常多

    大部分时间下推荐使用Runtime异常,一旦发生了自定义错误,程序只管抛出Runtime异常即可

    9.使用throw抛出异常

     当程序出现错误时,系统会自动抛出异常;java也允许程序自行抛出异常,自行抛出异常使用throw语句来完成

      9.1抛出异常

        同样一件事情,可能对你来说是好的,对别人来说是坏的。异常也一样,很多时候都要根据应用的业务要求来决定是否要抛出异常。

    由于业务需求不同产生的异常,必须由程序员来决定抛出,系统无法抛出这种异常。这时如果需要在程序中自行抛出异常,应使用throw语句,throw语句可以单独使用,throw抛出的不是异常类,而是一个异常实例

     如果是Checked异常,则该throw语句要么处于try块里,显示捕捉该异常,要么放在一个带throws声明抛出的方法里,把该异常交给调用者处理,该方法签名中也该用throws显示抛出该异常而Runtime异常,则该语句无须放在try块里,也无须放在带throws声明抛出的方法中。可以完全不理会。

          9.2自定义异常类

                     通常情况下,程序很少会自行抛出系统异常, 因为异常的类名通常也包含了该异常的有用信息。所以抛出异常时,应该选择合适的异常类,从而可以明确的描述该异常情况。在这种情况下,应用程序常常需要抛出自定义异常

               

    9.3 catch和throw同时使用

    前面介绍的异常处理有两种方式:

    1.在出现异常的方法内捕获并处理该异常,该方法的调用者将不会再次捕捉该异常

    2.该方法签名中声明抛出该异常,由方法调用者处理

    但有的时候该方法中,catch块仅仅能处理捕获到的异常的一部分,剩下的处理不了得交给他的调用者处理,这时就可以使用catch和throw相结合

    10.增强的throw语句

    实际上try块可能只抛出了FileNotFoundException异常,当时在java7以前,由于在捕获该异常时声明e的类型是Exception,因此编译器认为这段代码可能抛出Exception,所以包含这段代码的方法通常需要声明抛出Exception异常

    11.异常连

     

    中间层:业务逻辑处理

    持久层:保存数据

    当业务逻辑层访问持久层出现SQLException异常的时候,程序不应该把底层的SQLExcePtion传给用户,一是用户不想看到,另外把异常暴露给用户也不安全

    最常用的做法是:程序先捕获异常,然后抛出一个新的业务异常,新的业务异常对用户进行提示,这种处理方式叫做异常转移

    两种写法

     12.异常跟踪栈

    13.异常处理规则

    1.使程序代码混乱最小化

    2.捕获并保留诊断信息

    3.通知合适的人员

    4.采用合适的方式结束异常活动

  • 相关阅读:
    scm工作流部署问题解决
    mysql 数据库时间慢了8小时
    Vue加了二级路由后,跳转后js好像都失效
    flutter 莫名其妙错误集锦
    confluence-6.7.1 install
    git idea 项目复原
    springboot 本地jar发布,打war包
    flutter 初探2--点击按钮打开新窗口
    [转载]无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CI_AS_KS_WS" 之间的排序规则冲突
    [转载]天赋秉异的人永远是少数
  • 原文地址:https://www.cnblogs.com/wxw7blog/p/7082599.html
Copyright © 2020-2023  润新知