ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「基础」异常

2022-01-23 08:31:35  阅读:159  来源: 互联网

标签:Exception 处理 基础 try finally catch 异常


程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。

Java提供了优秀的解决办法:异常处理机制。

异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

  • try -- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
  • catch -- 用于捕获异常。catch用来捕获try语句块中发生的异常。
  • finally -- finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
  • throw -- 用于抛出异常。
  • throws -- 用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。

产生异常的原因:

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

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

三种类型的异常:

  • 检查性异常(编译异常):最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

Java异常的分类

异常的根接口Throwable,其下有2个子接口,Error和Exception。

  • Error:指的是JVM错误,这时的程序并没有执行,无法处理;
  • Exception:指的是程序运行中产生的异常,用户可以处理。

Java内置的异常类

Java 语言定义了一些异常类在 java.lang 标准包中。

标准运行时异常类的子类是最常见的异常类。由于 java.lang 包是默认加载到所有的 Java 程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。

Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。

 下面的表中列出了 Java 定义在 java.lang 包中的检查性异常类。

异常方法

下面的列表是 Throwable 类的主要方法:

异常的使用及执行流程

异常的处理方案

try...catch、try...catch...finally、try...finally

try{
    可能会发生的异常
}catch(异常类型 异常名(变量)){
    针对异常进行处理的代码
}catch(异常类型 异常名(变量)){
    针对异常进行处理的代码
}...
[finally{
    释放资源代码;
}]

注意点:

  • catch 不能独立于 try 存在。
  • catch里面不能没有内容
  • 在 try/catch 后面添加 finally 块并非强制性要求的。
  • try 代码后不能既没 catch 块也没 finally 块。
  • try里面越少越好。
  • try, catch, finally 块之间不能添加任何代码。
  • finally里面的代码最终一定会执行(除了JVM退出)
  • 如果程序可能存在多个异常,需要多个catch进行捕获。
  • 异常如果是同级关系,catch谁前谁后没有关系;如果异常之间存在上下级关系,上级需要放在后面

异常的执行流程

问题1:Error与Exception的区别

Error(错误)是系统中的错误,程序员是不能改变的和处理的,是在程序编译时出现的错误,只能通过修改程序才能修正。一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。

Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

问题2:在catch捕获异常时,为什么不考虑使用Throwable类型,而只是使用Exception来进行接收?

Throwable表示的范围要比Exception大。实际上程序使用Throwable来进行处理,没有任何语法问题,但是却会存在逻辑问题。因为此时出现的(或者说用户能够处理的)只有Exception类型,而如果使用Throwable接收,还会表示可以处理Error的错误,而用户是处理不了Error错误的,所以在开发中用户可以处理的异常都要求以Exception类为主。

问题3:异常是一起处理好还是分开处理好?

根据实际的开发要求是否严格来决定。在实际的项目开发项目工作中,所有的异常是统一使用Exception处理还是分开处理,完全根据开发者的项目开发标准来决定。如果项目开发环境严谨,基本上要求针对每一种异常分别进行处理,并且要详细记录下异常产生的时间以及产生的位置,这样可以方便程序维护人员进行代码的维护。再次注意:处理多个异常时,捕获范围小的异常要放在捕获范围大的异常之前处理。

问题4:throw和throws的区别?

throw和throws都是在异常处理中使用的关键字,区别如下:

  • throw:指的是在方法中人为抛出一个异常对象(这个异常对象可能是自己实例化或者抛出已存在的);
  • throws:在方法的声明上使用,表示此方法在调用时必须处理异常。

问题5:检查型异常(Checked Exception)与非检查型异常(Unchecked Exception)区别?

  • 所有的检查性异常都继承自java.lang.Exception;所有的非检查性异常都继承自java.lang.RuntimeEx ception。
  • 检查性异常和非检查性异常最主要的区别在于其处理异常的方式:检查性异常必须使用try catch或者throws等关键字进行处理,否则编译器会报错;非检查性异常一般是程序代码写的不够严谨而导致的问题,可以通过修改代码来规避。
  • 常见的运行时异常:空指针异常(NullPointerException)、除零异常(ArithmeticException)、数组越界异常(ArrayIndexOutOfBoundsException)等;
  • 常见的检查性异常:输入输出异常(IOException)、文件不存在异常(FileNotFoundException)、SQL语句异常(SQLException)等。

finally块和return

  • 首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。
  • finally中的return 会覆盖 try 或者catch中的返回值。
  • finally中的return或异常会抑制(消灭)前面try或者catch块中的异常。

自定义异常

为什么要创建自己的异常?

答:当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。 

应该在声明方法抛出异常还是在方法中捕获异常? 

答:捕捉并处理知道如何处理的异常,而抛出不知道如何处理的异常。、

在 Java 中你可以自定义异常。如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

按照惯例,自定义的异常应该总是包含如下的构造函数:

  • 一个无参构造函数
  • 一个带有String参数的构造函数,并传递给父类的构造函数。
  • 一个带有String参数和Throwable参数,并都传递给父类构造函数
  • 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

下面是IOException类的完整源代码,可以借鉴。

package java.io;
 
public class IOException extends Exception {
    static final long serialVersionUID = 7818375828146090155L;
 
    public IOException() {
    super();
    }
 
    public IOException(String message) {
    super(message);
    }
 
    public IOException(String message, Throwable cause) {
        super(message, cause);
    }
 
    public IOException(Throwable cause) {
        super(cause);
    }
}

 

吃水不忘挖井人:

 

标签:Exception,处理,基础,try,finally,catch,异常
来源: https://www.cnblogs.com/xfeiyun/p/15835684.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有