JAVA基础整合——异常

异常

    异常是什么???异常是指我们在执行一段程序期间所发生的一些错误。切记:这里是指的执行期间。后面我们也会提到一个“编译期间异常”,但是这个编译期间我是画了引号,后面我们会解释。
    从本质上来讲,异常是一个对象,对象一段实在程序执行过程中产生的(new),所以我们把异常的产生认定在运行期,这样认为有问题吗?答:没有问题。
    异常的产生和JVM默认的处理过程:

  1. 对于程序执行过程中发生的一些问题,JVM会首先根据这个问题的情况创建一个对应的异常对象,将这个对象向上抛出,就这样每一层一直抛出,最后会抛给main方法这里,也就是抛到程序入口这里之后,main方法向上抛,就会抛给JVM虚拟机处理。
  2. 虚拟机默认的处理:首先就会停止当前的程序的执行,并在控制的打印异常的信息。

1.异常的体系结构

一张简图帮我们回顾一下异常结构。
在这里插入图片描述
所有的异常类型都继承了顶级父类Throwable,所有的异常对象都是可以被抛出的。Throwable下面又分为两个分支:Error、Exception。

  1. Error:称为运行时错误,这种错误一旦发生程序员将无法做出提前的处理,只能停止程序的执行。Error错误描述了java运行时系统的内部错误和资源耗尽错误。大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM出现的问题。
  2. Exception:称为异常,这种异常可以在程序中做预处理。Exception下面又分为两个派系,一个时运行时异常,一个是”编译异常“:
    2.1 编译时异常:直接继承Exception。
    2.2 运行时异常:没有直接继承Exception,而是继承了RuntimeException。

注意: 这里我们要解释一下”编译“时异常,这里的编译不是指的异常出现的时机,而是说编译的时候JVM会给我们标出来这种写法过不了编译器,让我们做一下预处理的操作。所以,所有的异常产生都是在运行期。

2.编译时异常和运行时异常的区别

  • 所谓的编译时异常指的是这个异常必须在编译的时候需要我们做一下预处理操作,否则编译不通过。这种异常发生的概率很高,所以编译器不给通过。
  • 运行时异常,继承自RuntimeException,这种异常不要求程序做预处理,但是在运行的时候会停止整个程序的运行,最后由JVM抛出一个特定的异常。这种异常发生的概率很低,所以编译器可以放行。
  • 总结: 所以编译时异常和运行时异常是根据异常发生的概率进行划分的。

3.异常的处理

我们都知道JVM在面对异常的时候都会给我们提供一种解决方式,但是这种解决方式太“狠”了,会让我们整个程序宕机,所以我们尽量不要把异常抛给JVM处理,我们可以提前对这些异常做一个合理的预处理。
JAVA中为我们提供了两种异常处理方式:

  1. 将异常使用throws向上进行抛出,在方法定义的后面使用throws + 异常的类型。如下:
//可以抛出和当前异常类型完全一样的,也可以抛出它的父类的类型
 static void test02() throws FileNotFoundException

        我们不建议在main方法继续往上抛出,这样的话就会把异常给了JVM帮我们处理异常,我在前面也提到过为什么最好不要给JVM来帮我们处理异常。
        使用这种throws关键字向上抛出后,后续代码就不会再执行了,执行流程就会根据抛出点执行。

  1. 使用JAVA提供的try-catch块主动的再方法体中对产生的额异常进行处理,如下:
try{

	//可能发生异常的代码

}catch(异常类型 变量名){

	//对异常的处理过程

}

        这种处理方式后期的代码可以正常的执行,果try中的代码执行没有发生异常则不会去执行catch块,如果try中的代码执行过程中发生了异常则要执行catch对异常进行处理。
        在执行流程到catch中的时候系统会自动将异常对象赋值给指定的变量,catch方法中可以通过该变量了解异常的信息,并根据这个信息做出合理的处理。
        切记: catch方法中异常类型和实际产生的异常类型要兼容;注意这里我说的是兼容,也就是说可以是它的父类类型,这里也可以理解成一种多态,父类类型执行子类类型。

  • 两种异常处理方式的比较:
         throws这种方式优势是处理过程比较简单,但是从异常发生的那个位置开始往下的代码不在执行,try-catch这种方式是在发生异常的方法的内部进行显示的预处理,处理完成后方法后续代码可以继续执行。所以我们一般会将这两种方式结合使用,在项目中某格地方发生了异常不需要在这里去使用try-catch做预处理,而是将异常上抛,将所有的异常抛到一个统一的位置,在这个统一位置的处理中心对所有的异常进行统一处理。
  • 异常的出现具体位置:
         调用异常对象的getMessage()可以获取当前异常对象由于什么原因报错,还可以进一步调用对象的getStackTrace()获取异常发生的堆栈信息获取到对象发生异常的具体位置。实际开发中可以将获取的信息以文件方式持久化到磁盘上。

4.try-catch语句细节

  • 使用形式:
    try-catch
    try-catch-finally
    try finally

注意: finally也是一个语句块,这个表示无论是否发生异常都会执行这个语句块,连return都无法阻止它的执行,只有System.exit(0)才能阻止finally的执行。后面我们会把非托管类资源的关闭放在这里,如文件流的关闭,数据库的关闭。

  • 一个try可以配置多个catch,主要是因为一个try中可能发生多种不同类型的异常,但是应该按照异常的从小到大的顺序写catch。

5.throw 与 throws

  1. throw:表示自己进行异常处理,处理的时候有两种方式,要么自己捕获异常也就是try-catch,要么就抛出一个具体的异常类型。 throw一旦进入被执行,程序立即会转入异常处理阶段,后面的语句就不再执行。也就是:方法名(){ throw new Exception();}

  2. throws:用于声明异常,例如:如果一个方法里面不想有对异常代码的任何异常处理,那么就可以对这个方法进行声明可能产生的所有类型(通俗来说,就是在我这个方法贴上一个标签,把我会出现的异常都显示出来,然后看谁调用我就给谁处理)。也就是 :方法名(参数)异常类1,异常类2…

  3. 区别:throw抛出异常的类型为一个具体异常类型,而throws是用来声明一个方法可能抛出的所有异常信息,throws是将这些异常声明向上传并不做任何处理,最后看谁调用我,我就把异常交给谁处理。

6.自定义异常

虽然JAVA为我们编写程序提供了非常丰富的异常类型,但都是通用的,实际的开发中我们需要定义自己的异常类型

定义的步骤:

  1. 异常是一个类型,创建一个class,类名必须以Exception结尾
  2. 从Exception或者RuntimeException继承,自定义异常一般都是从RuntimeException继承
  3. 在自定义异常类中提供一些属性封装异常的信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值