【java核心技术】Java知识总结 -- 异常

目录

    • 异常
      • 异常的分类
      • 如何抛出一个异常
      • 创建异常类
      • 捕获异常


异常

异常的分类

下面为Java中异常的层次结构

【java核心技术】Java知识总结 -- 异常_第1张图片

【java核心技术】Java知识总结 -- 异常_第2张图片

在Java语言规范中将派生于Error类或RuntimeException类的所有异常类称为非检查异常,所有其它异常称为检查异常。

编译器将检查你是否为所有的检查型异常提供了异常处理器

【java核心技术】Java知识总结 -- 异常_第3张图片

如果出现前两种情况,则必须告诉调用这个方法的程序员有可能抛出的异常。

为什么?

因为任何一个抛出异常的方法都可能是一个死亡陷阱。如果没有没有处理器捕获这个异常,当前执行的线程就会终止。

有些Java方法包含对外界提供的类中,对于这些方法,应该通过方法的首部的异常规范声明这个方法可能抛出异常。

【java核心技术】Java知识总结 -- 异常_第4张图片

【java核心技术】Java知识总结 -- 异常_第5张图片

子类不能声明大于父类的检查型异常

如何抛出一个异常

【java核心技术】Java知识总结 -- 异常_第6张图片

【java核心技术】Java知识总结 -- 异常_第7张图片

创建异常类

【java核心技术】Java知识总结 -- 异常_第8张图片

自定义异常类的代码

public class FileFormatException extends IOException {
    public FileFormatException() {

    }
    public FileFormatException(String grip) {
        super(grip);
    }
}

测试代码

class A{
    String readData(BufferedReader in) throws FileFormatException{
        ...
        while(...){
            if(ch == -1){
                if(n<len){
                    throw new FileFormatException();
                }
                ...
            }
            return s;
        }
    }
}

下面是Throwable包中的一些常用的方法

【java核心技术】Java知识总结 -- 异常_第9张图片

捕获异常

有的代码必须要捕获异常,而捕获异常需要做出更多的规划。

如果发生了某个异常,但没有在任何地方捕获这个异常,程序就会终止,并在控制台上打印一个消息,其中包括这个异常的类型和一个堆栈轨迹。图形用户界面(GUI)程序(包括applet和应用程序)会捕获异常,打印堆栈轨迹消息,然后返回用户界面处理循环(在调试GUI程序时,最好保证控制台窗口可见,并且没有最小化)。

要想捕获一个异常,需要设置try/catch语句块。最简单的 try语句块如下所示:

【java核心技术】Java知识总结 -- 异常_第10张图片

如果try语句块中的任何代码抛出了catch子句中指定的一个异常类,那么

  1. 程序将跳过try语句块的其余代码。
  2. 程序将执行catch子句中的处理器代码。
  • 如果 try语句块中的代码没有抛出任何异常,那么程序将跳过catch子句。
  • 如果方法中的任何代码抛出了catch子句中没有声明的一个异常类型,那么这个方法就会立即退出(希望它的调用者为这种类型的异常提供了catch子句)。

为了展示捕获异常的处理过程,下面给出一个很典型的读取数据的代码:

【java核心技术】Java知识总结 -- 异常_第11张图片

【java核心技术】Java知识总结 -- 异常_第12张图片

【java核心技术】Java知识总结 -- 异常_第13张图片

请记住,编译器严格地执行throws 说明符。如果调用了一个抛出检查型异常的方法,就必须处理这个异常,或者继续传递这个异常。

哪种方法更好呢?一般经验是,要捕获那些你知道如何处理的异常,而继续传播那些你不知道怎样处理的异常。

如果想传播一个异常,就必须在方法的首部添加一个throws 说明符,提醒调用者这个方法可能会抛出异常。

查看Java API文档,可以看到每个方法可能会抛出哪些异常,然后再决定是由自己处理,还是添加到throws列表中。对于后一种选择,不用感到难堪。将异常交给胜任的处理器进行处理要比压制这个异常更好。

同时请记住,这个规则也有一个例外。前面曾经提到过:如果编写一个方法覆盖超类的方法,而这个超类方法没有抛出异常(如JComponent中的paintComponent),你就必须捕获你的方法代码中出现的每一个检查型异常。不允许在子类的throws说明符中出现超类方法未列出的异常类。

你可能感兴趣的:(#,Java核心技术,java,异常,基础)