为什么我们需要在 Java 中处理或抛出已检查的异常?

Why we need to handle or throw checked exceptions in Java?

我是 Java 的新手,我读到仅在编译时引发已检查的异常,即如果存在未处理或抛出的已检查异常,程序将无法成功编译。 如果有什么东西阻止了编译器编译代码,那么我们可以将其擦除或以另一种方式重新编码,这样问题就不存在了。

例如,如果我们试图打开一个系统中不存在的文件,我们不应该直接打开它。那么为什么需要 handle/throw 这些异常?

必须处理 Java 中的检查异常,这就是为什么编译器会抱怨并且没有编译代码的原因。

但是直到运行时才会引发异常本身,以防万一。

当您编写代码时,您应该正确处理所有已检查的异常,因此您必须编写一个 try catch 块或仅 return 方法中的异常。

如果您使用某些引发检查异常的库,您可以使用我已经解释过的两种方式之一进行处理。

但在您的代码中您可以选择使用未经检查的异常。

这些异常可以忽略,编译器会很好。 当然,如果在执行过程中引发了其中一个未经检查的异常并且未被捕获,您的应用程序将会崩溃。

但是在某些情况下这可能是可取的,在这种情况下没有正确的方法来处理异常并且它通常是 Error.

的子类

无论如何,你不应该考虑如何处理代码中的错误情况,而应该只考虑异常。

更多:Exception class, Error class

您不应将异常处理视为问题,而应将其视为功能。

假设不存在例外。

var file = new File("test.txt");
if (!file.exists()) {
    file.createNewFile();
}
var writer = new FileWriter(file);
// ...

会出现什么问题?

  • 在检查文件是否存在和打开 reader 之间,该文件可能已被另一个 thread/process 删除。所以即使你创建了它,它也不见了 -> 你需要以某种方式锁定文件
  • 您的内存已满,因此无法创建文件 -> 您需要检查 createNewFile 的结果。
  • 文件存在,但是是一个目录。
  • 文件被锁定,因为另一个进程正在写入它 -> 您需要检查它是否正在写入。

这样就可以了(仍然假设没有例外):

var file = new File("test.txt");
if (!file.exists()) {
    if(file.createNewFile()) {
        if (!file.isDirectory()) {
            if (!isUsed(file)) {
                var writer = new FileWriter(file);
                // ...
            }
        }
    }
}

代码很多,还是没有解决第一个问题。

鉴于

var file = new File("test.txt");
try {
    var writer = new Filewriter(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

更短、更清晰、更容易理解。

此外,通常情况下,发生这些问题的可能性更大。因此,与其假设所有最坏的情况并事先进行多次检查,不如假设最好的情况,如果出现问题,您会寻找原因。

这也会影响 运行时间。如果您 运行 no-exception 代码 1000 次,则所有这些检查都将 运行 1000 次,无论它们是否失败。对于 exception-code,情况并非如此,可能根本不会 运行。

你的概念性问题是你混淆了编译时发生的事情和 运行 时发生的事情;即当程序由程序员 编译时 以及当它由用户 运行 编译时 .

在编译时,编译器分析程序以确定可以抛出哪些异常。例如

public static void main(String[] args) {
    FileInputStream fis = new FileInputStream(args[0]);  // HERE
}

FileInputStream(String) 构造函数声明为 throws IOException。 (查找。)因此编译器知道 HERE 处的语句可能 抛出 IOExceptionIOException 是一个已检查的异常。 (查一下。)

它不知道它。它不可能知道它 ... 因为它不知道 args[0] 将包含什么。那只有在 运行 时间才知道;即当程序是 运行 并且用户提供一些命令行参数时。

问:这里 checked exception 是什么意思?

嗯,这意味着 main 方法要么必须声明为(例如)throws IOException,要么必须在 try-catch[= 中捕获它63=]声明。

问:那么为什么是 checked 异常?

因为它是那样声明的!

问:为什么这样声明?

为了强制程序员处理可能性打开的文件不存在,不可读等在。当程序(最终)运行.

编译器说“对可能发生的事情做一些事情......”。


重申一下。编译器无法 检查文件是否存在,因为它不知道用户将要 提供的路径名。即使它确实知道,并且它检查1 该文件在编译时存在,它无法 知道该文件是否 going 在 运行 时间仍然存在,可能在不同网络上的完全不同的机器上......未来很多年。

1 - 这是假设。它不检查。这将毫无意义。