[Java异常]异常

Throwable 是 Java 语言中所有错误与异常的超类。
Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。
Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。

image

Error(错误)

Error 类及其子类:程序中无法处理的错误,表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时 JVM 出现问题。

通常有 VirtualMachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如 OutOfMemoryError:内存不足错误;StackOverflowError:栈溢出错误。
此类错误发生时,JVM 将终止线程。这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!

Exception(异常)

程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。

运行时异常都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

非运行时异常 (编译异常)是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)

可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

不可查异常(编译器不要求强制处置的异常)包括运行时异常(RuntimeException与其子类)和错误(Error)。

在Java中,错误(Error)和异常(Exception)都是继承自 Throwable 类的子类,但它们在性质和处理上有着明显的区别。

Error(错误)#

Error 类及其子类表示系统级的异常,通常是由于JVM本身的问题引起的。这些错误通常表示更严重的问题,程序一般不应尝试捕获和处理这些错误。

常见的错误类型:#

  • OutOfMemoryError: 当JVM没有足够的内存来分配给对象时抛出。
  • StackOverflowError: 当JVM的栈内存被耗尽,通常是由于递归方法调用过多导致的。
  • VirtualMachineError: 当JVM出现某些内部错误或资源耗尽时抛出。

特点:#

  • 这些错误通常是不可恢复的。
  • 通常不需要(也不建议)程序员去捕获和处理它们。

Exception(异常)#

Exception 类及其子类表示程序本身可以处理的情况。异常是可以通过捕获和处理来恢复的。

常见的异常类型:#

  • IOException: 输入/输出操作失败或中断时抛出。
  • SQLException: 数据库操作失败时抛出。
  • NullPointerException: 尝试访问null对象的方法或属性时抛出。
  • IndexOutOfBoundsException: 当索引超出范围时抛出。

特点:#

  • 分为受检异常(Checked Exception)和非受检异常(Unchecked Exception)。
  • 可以使用try-catch块捕获和处理。
  • 程序应合理地捕获和处理异常,以确保程序的健壮性和用户体验。

受检异常(Checked Exception)#

受检异常是编译时异常,必须在方法声明中进行处理(使用throws关键字)或者在方法内部捕获(使用try-catch块)。这些异常通常是程序本身之外的条件导致的,需要程序员进行预防和处理。

常见的受检异常:#

  • IOException
  • SQLException
  • ClassNotFoundException

非受检异常(Unchecked Exception)#

非受检异常是运行时异常,程序不强制要求处理。这些异常通常是程序中的错误导致的,比如逻辑错误或编程错误。

常见的非受检异常:#

  • NullPointerException
  • ArrayIndexOutOfBoundsException
  • IllegalArgumentException

代码示例#

Error 示例:#

public class ErrorExample {
    public static void main(String[] args) {
        try {
            causeStackOverflow();
        } catch (StackOverflowError e) {
            System.err.println("Caught StackOverflowError: " + e.getMessage());
        }
    }

    public static void causeStackOverflow() {
        causeStackOverflow(); // 无限递归调用
    }
}

Exception 示例:#

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ExceptionExample {
    public static void main(String[] args) {
        try {
            readFile("nonexistentfile.txt");
        } catch (FileNotFoundException e) {
            System.err.println("Caught FileNotFoundException: " + e.getMessage());
        }
    }

    public static void readFile(String fileName) throws FileNotFoundException {
        File file = new File(fileName);
        Scanner scanner = new Scanner(file);
        while (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
        scanner.close();
    }
}

总结#

  • 错误(Error)表示系统级问题,通常不可恢复,不建议捕获和处理。
  • 异常(Exception)表示程序本身可以处理的情况,分为受检异常(需要处理)和非受检异常(可以选择处理)。
  • 处理异常是编写健壮的Java应用程序的重要部分,而错误一般由JVM处理。

throw和throws的区别#

  • throw 在方法体内使用,throws 在方法声明上使用;

  • throw 后面接的是异常对象,只能接一个。throws 后面接的是异常类型,可以接多个,多个异常类型用逗号隔开;

  • throw 是在方法中出现不正确情况时,手动来抛出异常,结束方法的,执行了 throw 语句一定会出现异常。而 throws 是用来声明当前方法有可能会出现某种异常的,如果出现了相应的异常,将由调用者来处理,声明了异常不一定会出现异常。

其中,throw 是用在某个方法的方法体内的,当我们认定某种情况不合理时,就可以创建异常对象,封装好异常信息,然后通过 throw 来抛出异常并终止该方法。

public class Student {
    // 性别
    private String gender;

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        if (!("男".equals(gender) || "女".equals(gender))) {
            throw new IllegalArgumentException("非法性别:" + gender);
        }
        this.gender = gender;
    }
}

而 throws 是用在某个方法的方法声明上的,表示当前方法如果抛出了某些异常,将由调用者来进行异常处理。这种方式也可以让调用者知晓该对哪些异常进行处理。throws 声明的异常不一定会出现,只是一种可能。

public class FileInputStream extends InputStream {
    public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }
}

作者:Esofar

出处:https://www.cnblogs.com/DCFV/p/18312601

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Duancf  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示