java 基础 异常

168 阅读6分钟

Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字,其中try关键字后紧跟一个花括号扩起来的代码块(花括号不可省略),简称try块,它里面放置可能引发异常的代码。catch后对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块。多个catch块后还可以跟一个finally块,finally块用于回收在try块里打开的物理资源,异常机制会保证finally块总被执行。throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常;而throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象。

[D1SMt0.png

Checked异常和Runtime异常

Checked异常和Runtime异常, Java认为Checked异常都是可以在编译阶段被处理的异常,所以它强制程序处理所有的Checked异常;而Runtime异常则无须处理。Checked异常可以提醒程序员需要处理所有可能发生的异常,但Checked异常也给编程带来一些烦琐之处,所以Checked异常也是Java领域一个备受争论的话题。

不要在finally块中使用如return或throw等导致方法终止的语句,(throw语句将在后面介绍),一旦在finally块中使用了return或throw语句,将会导致try块、catch块中的return、throw语句失效。看如下程序。

public class FinallyFlowTest {

    public static void main(String[] args) throws Exception {
        boolean a = test();
        System.out.println(a);
    }
    public static boolean test() {
        try {
            // 因为finally块中包含了return语句
            // 所以下面的return语句失去作用return true;
        } finally {
            return false;
        }
    }
}

如果有finally块,系统立即开始执行finally块——只有当finally块执行完成后,系统才会再次跳回来执行try块、catch块里的return或throw语句;如果finally块里也使用了return或throw等导致方法终止的语句,finally块已经终止了方法,系统将不会跳回去执行try块、catch块里的任何代码

throws语句

  • 用了throws来声明抛出IOException异常,一旦使用throws语句声明抛出该异常,程序就无须使用try...catch块来捕获该异常了
  • 使用throws声明抛出异常时有一个限制,就是方法重写时“两小”中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。
  • 如果需要在程序中自行抛出异常,则应使用throw语句:throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例。throw语句的语法格式如下:throw ExceptionInstance;

异常使用指南:

  1. 在恰当的级别处理问题。
  2. 解决问题并且重新调用产生异常的方法
  3. 进行少许修补,然后绕过异常发生的地方继续执行
  4. 用别的数据进行计算,以代替方法预计返回的值
  5. 把当前运行环境下能做的事情尽量做完,然后把相同的异常重新抛到更高层
  6. 把当前运行环境下能做的事情尽量做完,然后把不同的异常重新抛到更高层
  7. 终止程序
  8. 进行简化
  9. 让类库和程序更安全

异常常见的面试题:

Q&A java中用来抛出异常的关键字是什么?

throw

Q&A 异常和Error(错误)的区别?

error:是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。 Exception :表示可恢复的例外,这是可捕捉到的

Q&A 什么是异常?

所谓异常是指程序在运行过程中发生的一些不正常事件。(如:除0溢出,数组下标越界,所读取的文件不存在)

Q&A 什么类是所有异常类的父类

Throwable类

Q&Ajava 虚拟机能自动处理的异常是什么?

运行异常

Q&A Try-catch-finally的执行过程

(1)try{}语句块中放的是要检测的java代码,可能有会抛出异常,也可能会正常执行 (2)catch(异常类型){}块是当java运行时系统接收到try块中所抛出异常对象时,会寻找处理这一异常catch块来进行处理(可以有多个catch块) (3)finally{}不管系统有没有抛出异常都会去执行,一般用来释放资源。除了在之前执行了System.exit(0)

Q&A 常见的异常?你的理解。

常见异常:RuntimeException,IOException,SQLException,ClassNotFoundException

Q&A final, finally, finalize的区别。

final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。(在垃圾回收的时候会调用被回收对象的此方法。

Q&AJava 中的异常处理机制的简单原理和应用。

​ 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

Q&A 运行时异常与一般异常有何异同?

Java提供了两类主要的异常:运行时异常runtime exception和一般异常checked exception。checked 异常。对于后者这种异常,JAVA要求程序员对其进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。 运行时异常我们可以不处理。这样的异常由虚拟机接管。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

Q&A 你平时在项目中是怎样对异常进行处理的。

(1)尽量避免出现runtimeException 。例如对于可能出现空指针的代码,带使用对象之前一定要判断一下该对象是否为空,必要的时候对runtimeException

也进行try catch处理。

(2)进行try catch处理的时候要在catch代码块中对异常信息进行记录,通过调用异常类的相关方法获取到异常的相关信息,返回到web端,不仅要给用户良好

的用户体验,也要能帮助程序员良好的定位异常出现的位置及原因。