Java异常Error和Exception的区别「建议收藏」

Java异常Error和Exception的区别「建议收藏」异常发生的原因有很多,通常包含以下几大类:用户输入了非法数据。要打开的文件不存在。网络通信时连接中断,或者JVM内存溢出。这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个

大家好,又见面了,我是你们的朋友全栈君。

Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。

Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。

Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。

Exception 又分为可检查(checked)异常不检查(unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。前面我介绍的不可查的 Error,是 Throwable 不是 Exception。

不检查异常就是所谓的运行时异常,类似 NullPointerException、ArrayIndexOutOfBoundsException 之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
这里写图片描述

异常发生的原因有很多,通常包含以下几大类:

  • 用户输入了非法数据。
  • 要打开的文件不存在。
  • 网络通信时连接中断,或者JVM内存溢出。

这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:

  • 检查性异常:(非运行时异常)最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。原则上如果不处理,程序就不能编译通过。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
    从图中可以看出所有异常类型都是内置类Throwable的子类,因而Throwable在异常类的层次结构的顶层。

接下来Throwable分成了两个不同的分支,一个分支是Error,它表示不希望被程序捕获或者是程序无法处理的错误。另一个分支是Exception,它表示用户程序可能捕捉的异常情况或者说是程序可以处理的异常。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常。

下面将详细讲述这些异常之间的区别与联系:

Error:

  • Error类对象由 JVM生成并抛出,大多数错误与代码编写者所执行的操作无关。例如,Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在Java中,错误通常是使用Error的子类描述。

Exception:

  • 在Exception分支中有一个重要的子类RuntimeException(运行时异常),该类型的异常自动为你所编写的程序定义ArrayIndexOutOfBoundsException(数组下标越界)、NullPointerException(空指针异常)、ArithmeticException(算术异常)、MissingResourceException(丢失资源)、ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
  • 而RuntimeException之外的异常我们统称为非运行时异常,类型上属于Exception类及其子类,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
    这里写图片描述
    1、try{} 里有一个 return 语句,那么紧跟在这个 try 后的 finally{} 里的 code 会不会被执行,什么时候被执行,在 return 前还是后?

答案:会执行,在方法返回调用者前执行。

2、Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

答:Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并可以对其进行处理。

Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果系统会抛出(throw)一个异常对象,可以通过它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;try用来指定一块预防所有异常的程序;catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型;throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally为确保一段代码不管发生什么异常状况都要被执行;try语句可以嵌套,每当遇到一个try语句,异常的结构就会被放入异常栈中,直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这种异常的try语句或者最终将异常抛给JVM。

3、运行时异常与受检异常有何异同?

答:异常表示程序运行过程中可能出现的非正常状态。
①运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。
②受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。
Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。
异常和继承一样,是面向对象程序设计中经常被滥用的东西,在Effective Java中对异常的使用给出了以下指导原则:

  • 不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)
  • 对可以恢复的情况使用受检异常,对编程错误使用运行时异常
  • 避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常的发生)
  • 优先使用标准的异常
  • 每个方法抛出的异常都要有文档
  • 保持异常的原子性
  • 不要在catch中忽略掉捕获到的异常

NoClassDefFoundError 是个Error,是指一个class在编译时存在,在运行时找不到了class文件了;ClassNotFoundException 是个Exception,是使用类似Class.foName()等方法时的checked exception。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158552.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 今儿下午疲惫极了_形容疲惫至极的诗句

    今儿下午疲惫极了_形容疲惫至极的诗句回家的公车上人也特别的多,春天来了,气温渐温,街上的颜色也丰富起来,我一路的走,一路的观望,看着一张张的笑脸,我也一路的想,想我爱的人和爱我的人,不觉得走神了。下车没两步,我摔了一交,结结实实的。手中的电脑包抛了老远,我一下子倒在了路边,脑子嗡响了一下,暂时的记忆就没了。大约有那么两三秒,也许是我摔倒的动静太大了,感觉周围的目光都在朝我这边看,一时间的尴尬,没顾得上身上的土,站起来就往住的方向猛走

  • java mina框架实例_MINA框架简介和一个简单的例子

    基于MINA框架快速开发网络应用程序1.MINA框架简介MINA(MultipurposeInfrastructureforNetworkApplications)是用于开发高性能和高可用性的网络应用程序的基础框架。通过使用MINA框架可以可以省下处理底层I/O和线程并发等复杂工作,开发人员能够把更多的精力投入到业务设计和开发当中。MINA框架的应用比较广泛,应用的开源项目有Apache…

  • Windows程序设计:MFC 、Winform 和 WPF 比较[通俗易懂]

    MFC生成本机代码,自然是很快,可是消息循环减缓了界面显示速度。WinForm封装了win32的api,多次进行P/invoke操作(大部分使用p/invoke操作封装),速度慢。WPF是一种新的模型,不再使用win32模型,自己新建模型,使用dx作为新的显示技术,直接访问驱动程序,加快了运行速度,可是,这种模型,需要支持dx9的显卡,硬件要求高(你还能找到现代机器不支持dx9的吗?)…

  • vue父组件调用子组件属性_vue子组件获取父组件实例

    vue父组件调用子组件属性_vue子组件获取父组件实例在vue2中,子组件调用父组件,直接使用this.$emit()即可。但是在vue3中,很显然使用this.$emit()已经开始报错了,为什么会报错呢?原因是:在vue3中setup是在声明周期beforeCreate和created前执行,此时vue对象还未创建,因此我们无法使用this。那么我们在vue3中,子组件该如何调用父组件的函数呢?方法一:首先写一个Child.vue,重点在setup函数中引入context形参,配合emit使用。定义了两个函数,toFather

  • java中switch的用法和逻辑运算符[通俗易懂]

    java中switch的用法和逻辑运算符[通俗易懂]一、switch的用法常见用法如下:importjava.util.Scanner;publicclassA{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intscore=sc.nextInt();if(score>100&&score<0){Syst

  • 浅谈软件性能提升相关的概念

    浅谈软件性能提升相关的概念浅谈软件性能提升相关的概念原文链接为<Makingyourprogramrunfaster:thekeyconceptsofsoftwareperformance-Jo

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号