Java 异常知识点一篇没够再来一篇

createh53个月前 (02-01)技术教程24

Java 异常处理使用

前一章已经详细地讲解对应的基础例子, 但是并没有把使用方式全部写出来, 这一章我们来详细地把使用方法说一说。

基础使用,try catch 语句。这里可以参看上一篇文章。接下来说说多个异常的情况。

先创建两个继承自 Exception 的异常类, 等下要用, 分别是: ParamException 和 LogicException 。

public class ParamException extends Exception {

    public ParamException() {
    }

    public ParamException(String message) {
        super(message);
    }

    public ParamException(Throwable cause) {
        super(cause);
    }

    public ParamException(String message, Throwable cause) {
        super(message, cause);
    }

    public ParamException(String message, Throwable cause, 
                          boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
}
public class LogicException extends Exception {

    public LogicException() {
    }

    public LogicException(String message) {
        super(message);
    }

    public LogicException(Throwable cause) {
        super(cause);
    }

    public LogicException(String message, Throwable cause) {
        super(message, cause);
    }

    public LogicException(String message, Throwable cause, 
                          boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
}

抛出异常使用 throw 关键字, 使用方法如下:

throw new ParamException("参数错误,请验证您的参数是否正确!");

这里多说一句, 就是对于异常来说, 有两种情况, 一种是继承 RuntimeException 异常的, 另一种是继承非 RuntimeException 以及子类的。区别是是否需要显式地使用 throws 抛出异常。RuntimeException 异常不需要显式地抛出。

显式的继续往上抛出以上使用 throws 关键字。使用方法格式如下:

 void test(String s) throws ParamException

这里如果是需要抛出异常, 没有捕获, 也没有往上抛出, 就会报错, 错误如下:

并且在抛出之后,在上层依然可以选择抛出和捕获, 代码能控制的最上层没有捕获的情况下, 还往上抛出, 就由 Java 虚拟机进行捕获并打印出对应的异常。例如:

public static void main(String[] args) throws ParamException

当然也可以直接捕获, 例如:

基础的用法就引申这么多, 接下来看看其他的使用方式。

多个 catch 语句

如果有多个异常的情况下, 就需要根据异常的从小到大进行捕获,或者就写最上层的 Exception 异常。 因为该异常是所有异常类的父类, 所以捕获它就不需要多个 catch 的情况了。 举例需要多个 catch 语句:

如果不想写多个 catch 就可以使用父类 Exception 进行捕获。

如果抛出异常,却没有捕获,或者没有写全, 就会抛出错误。错误信息如下:

多 catch 的优化

对于多个异常, 又不想写多个 catch 语句, 有没有办法呢, 答案是有的, 可以使用 “|” 来分割多个异常信息。 举例说明:

非常容易理解, 且符合规则,能一手抓住, 就不要下两次手。

异常中再抛出异常

除了上面简单的异常, 还会遇到异常中再抛出异常的。 大多数情况下这个问题出现在 IO 操作, 以及 SQL 操作, 需要关闭资源, 但是关闭资源有会出现关闭异常的问题, 需要关闭的已经关闭了。 或者需要打开的已经打开了。

finally

让我们先下一个例子, 然后再说 finally 的使用规则。

demo06.again("");
System.out.println("继续执行业务,查看我的输出。");

查看上面的代码, 发现, 在抛出异常的时候, 并没有执行第 6 行的代码。而是直接退出程序了。 如果说, 对于业务来说, 如果出现了异常不应该直接退出, 而是做一些善后的工作?或者说必须不管是否抛出异常,都要执行的代码。 这个时候, Java 异常体系中就可以使用关键字 finally 了。它的含义是, 不管是否抛出异常都将执行该代码。

上面的代码只是为了演示其用法, 并没有真实的意义, 使用一个真实的小例子来说一下。

该案例的是读取相同目录中 Demo01.java 文件的内容。 因为编写代码的时候都是使用 UTF-8 的格式。所以需要看你的系统默认是什么格式, 我这默认的是 GB18030 所以进行了转码。案例如下:

运行查看效果:

这里你将发现,使用了 finally 语法将没有关闭的 IO 操作进行关闭。任何资源的打开都需要关闭, 否则资源一直使用却不清理,总会把资源占满。 而影响程序的使用。

简化 try 语法 try-with-resources

对于 try-with-resources 是 Java 7 引入的语法结构。主要原因是为了使代码更加易读,更清晰的管理代码。

根据上面的一个例子, 可以改造成简化的语法。 代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo08 {
    public static void main(String[] args) {
        File file = new File("Demo01.java");
        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
                BufferedReader reader = new BufferedReader(isr)) {
            // 转换编码格式为 UTF-8 否则可能会有乱码
            String tempString = null;
            int line = 1;
            // 循环读取文件, 当文件为 null 结束循环。
            while ((tempString = reader.readLine()) != null) {
                System.out.println("line " + line + ": " + tempString);
                line++;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行测试查看效果:

从代码上看, 首先代码量大量减少, 并且不需要关关闭的顺序, 程序会自动判断。 为什么能判断到, 主要是因为 Closeable 接口的原因, 如果想自动关闭, 必须实现接口 AutoCloseable。而 Closeable 继承了 AutoCloseable。 实现对应的唯一的方法:

public void close() throws IOException

只要实现该方法, 即可使用该语法。推荐后续都使用该语法, 以防你在写代码的时候, 忘记关闭必要的需要关闭的资源。

而 InputStreamReader 类同样继承了 Reader 抽象类,所以一样可以使用该简化的方式。

本来觉得上一篇异常足够了, 没想到又简单写写又写了一篇。这次应该把异常相关的内容写得差不多了吧?当然使用起来还要灵活应用。希望对你有所帮助。

关注, 点赞, 收藏。 感谢您的阅读。

相关文章

终于有人把所有的Java异常处理方法给总结出来了

背景 最近专门负责团队的项目质量。我在治理异常日志过程中,总结了一下Java的异常处理。上面是我整理的最近自己比较常见的异常知识地图。异常知识地图概述 从异常知识地图最左边的根开始看,地图从左到右...

初识java—(四十七)异常处理(异常处理 java)

Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字,其中try关键字后面紧跟着一个花括号括起来的代码块,它里面放置可能会引发异常的代码块。catch后面...

Java 异常处理通关指南(java异常处理是怎样实现的)

前言在理想世界中,程序永远不会出现问题,用户输入的数据永远是正确的,逻辑没有任何问题 ,选择打开的文件也一定是存在的,内存永远是够用的……!但是现实世界里一旦出现这些问题,如果处理不好,程序就不能正常...

三十七、Java异常处理(java异常处理步骤)

在Java编程中,异常处理是一项至关重要的技能,让我们能够有效地应对程序运行过程中可能出现的各种错误状况,从而使程序更具健壮性。什么是异常?Java异常是程序运行时出现的问题或错误的表示,代表了程序正...

异常处理,JAVA中异常处理的介绍(java中异常处理机制是怎样的)

异常处理的介绍在Java程序的运行过程中,如果Java虚拟机检测出一个无法执行的操作,就会产生运行时错误(runtime error)在Java中,运行时错误会作为异常来抛出。抛出的异常是一个对象,该...

关于Java Exception异常的深入用法及实例

关于Java Exception异常的深入用法及实例一、异常的概念生活中的异常:例如感冒发烧,工作时电脑蓝屏、死机等。程序中的异常:在程序运行的过程中,也会发生这种非正常状况,例如程序运行时磁盘空间不...