为什么我们需要在 Java 中处理或抛出已检查的异常?
Why we need to handle or throw checked exceptions in Java?
我是 Java 的新手,我读到仅在编译时引发已检查的异常,即如果存在未处理或抛出的已检查异常,程序将无法成功编译。
如果有什么东西阻止了编译器编译代码,那么我们可以将其擦除或以另一种方式重新编码,这样问题就不存在了。
例如,如果我们试图打开一个系统中不存在的文件,我们不应该直接打开它。那么为什么需要 handle/throw 这些异常?
必须处理 Java 中的检查异常,这就是为什么编译器会抱怨并且没有编译代码的原因。
但是直到运行时才会引发异常本身,以防万一。
当您编写代码时,您应该正确处理所有已检查的异常,因此您必须编写一个 try catch
块或仅 return 方法中的异常。
如果您使用某些引发检查异常的库,您可以使用我已经解释过的两种方式之一进行处理。
但在您的代码中您可以选择使用未经检查的异常。
这些异常可以忽略,编译器会很好。
当然,如果在执行过程中引发了其中一个未经检查的异常并且未被捕获,您的应用程序将会崩溃。
但是在某些情况下这可能是可取的,在这种情况下没有正确的方法来处理异常并且它通常是 Error
.
的子类
无论如何,你不应该考虑如何处理代码中的错误情况,而应该只考虑异常。
您不应将异常处理视为问题,而应将其视为功能。
假设不存在例外。
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
处的语句可能 抛出 IOException
。 IOException
是一个已检查的异常。 (查一下。)
它不知道它会。它不可能知道它 将 ... 因为它不知道 args[0]
将包含什么。那只有在 运行 时间才知道;即当程序是 运行 并且用户提供一些命令行参数时。
问:这里 checked exception 是什么意思?
嗯,这意味着 main
方法要么必须声明为(例如)throws IOException
,要么必须在 try-catch[= 中捕获它63=]声明。
问:那么为什么是 checked 异常?
因为它是那样声明的!
问:为什么这样声明?
为了强制程序员处理可能性打开的文件不存在,不可读等在。当程序(最终)运行.
编译器说“对可能发生的事情做一些事情......”。
重申一下。编译器无法 检查文件是否存在,因为它不知道用户将要 提供的路径名。即使它确实知道,并且它检查1 该文件在编译时存在,它无法 知道该文件是否 going 在 运行 时间仍然存在,可能在不同网络上的完全不同的机器上......未来很多年。
1 - 这是假设。它不检查。这将毫无意义。
我是 Java 的新手,我读到仅在编译时引发已检查的异常,即如果存在未处理或抛出的已检查异常,程序将无法成功编译。 如果有什么东西阻止了编译器编译代码,那么我们可以将其擦除或以另一种方式重新编码,这样问题就不存在了。
例如,如果我们试图打开一个系统中不存在的文件,我们不应该直接打开它。那么为什么需要 handle/throw 这些异常?
必须处理 Java 中的检查异常,这就是为什么编译器会抱怨并且没有编译代码的原因。
但是直到运行时才会引发异常本身,以防万一。
当您编写代码时,您应该正确处理所有已检查的异常,因此您必须编写一个 try catch
块或仅 return 方法中的异常。
如果您使用某些引发检查异常的库,您可以使用我已经解释过的两种方式之一进行处理。
但在您的代码中您可以选择使用未经检查的异常。
这些异常可以忽略,编译器会很好。 当然,如果在执行过程中引发了其中一个未经检查的异常并且未被捕获,您的应用程序将会崩溃。
但是在某些情况下这可能是可取的,在这种情况下没有正确的方法来处理异常并且它通常是 Error
.
无论如何,你不应该考虑如何处理代码中的错误情况,而应该只考虑异常。
您不应将异常处理视为问题,而应将其视为功能。
假设不存在例外。
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
处的语句可能 抛出 IOException
。 IOException
是一个已检查的异常。 (查一下。)
它不知道它会。它不可能知道它 将 ... 因为它不知道 args[0]
将包含什么。那只有在 运行 时间才知道;即当程序是 运行 并且用户提供一些命令行参数时。
问:这里 checked exception 是什么意思?
嗯,这意味着 main
方法要么必须声明为(例如)throws IOException
,要么必须在 try-catch[= 中捕获它63=]声明。
问:那么为什么是 checked 异常?
因为它是那样声明的!
问:为什么这样声明?
为了强制程序员处理可能性打开的文件不存在,不可读等在。当程序(最终)运行.
编译器说“对可能发生的事情做一些事情......”。
重申一下。编译器无法 检查文件是否存在,因为它不知道用户将要 提供的路径名。即使它确实知道,并且它检查1 该文件在编译时存在,它无法 知道该文件是否 going 在 运行 时间仍然存在,可能在不同网络上的完全不同的机器上......未来很多年。
1 - 这是假设。它不检查。这将毫无意义。