gpt4 book ai didi

java - 为什么要在 Java 中使用异常处理?

转载 作者:行者123 更新时间:2023-12-03 21:28:26 24 4
gpt4 key购买 nike

我在 SO 上阅读了很多关于 java 异常处理的帖子,但我确实得到了满意的答案。我为什么要把它们放在我的代码中?

  1. 我想使用 JRE 的一些 api 方法,这些方法是用已检查的异常制作的。所以如果我想使用它们,我需要抛出或捕获异常(例如 Java I/O)。这是在我的类里面使用异常的合理规则吗?
  2. 我听说过这件事

Java exception handlings make separating error handling codes from my business logic

下面代码段中的分离错误处理在哪里?

public int division(int divident, int divisor) {
int result = 0;
try {
result = divident / divisor;
} catch (ArithmeticException e) {
System.out.println("Divisor must not be zero !");
}
return result;
}

3。 Java 的默认异常处理使得在标准输出中显示异常信息并终止程序。我是否自己使用异常处理来避免我的程序终止?

最佳答案

这是三个问题,但这并不是这里第一次出现这种情况。 :-)

  1. 是的,您必须处理它们或声明它们,因为它们是已检查的异常。您必须这样做的原因是调用您的代码的代码知道您的代码可能失败的方式(因为您已经声明了它可以抛出的异常)。

  2. 该代码段非常简单,因此分离和好处并不是那么清楚。但是考虑打开两个流,从一个流复制到另一个流,使用转换代码(包括对从属方法的调用)。您最终会得到一个包含 10-20 条语句的方法体。无需检查每个 I/O 语句是否有效,您只需将逻辑包装在 IOException 处理程序中,知道任何 I/O 异常都会跳出主逻辑进入处理程序。

  3. 这取决于您编写的程序类型,但通常您会在最合适的级别处理异常,这通常在您的程序中处于多个级别。最外层只处理真正非常不寻常的不可恢复的异常,要么让默认处理做它做的事情,要么使用一个包罗万象的处理程序来做类似的事情但可能(尝试)记录失败其他地方(如日志文件)也是如此:

    public class MyProgram {
    public static final void main(String[] args) {
    try {
    // Run...
    }
    catch (Throwable t) {
    // Handle the fact that something went wrong here, if you can
    // Usually this would be only for really, really unusual errors,
    // otherwise you would have handled them earlier
    }
    }
    }

为了强调 #2 中的观点,考虑两种 process 方法,一种在 Java 中有异常,另一种在没有异常的假设的类似 Java 的语言中:

Java 的:

private void process() {
try ( // <== Main logic
Reader fr = new FileReader(this.sourceFileName); // <== Main logic
BufferedReader br = new BufferedReader(fr); // <== Main logic
Writer fw = new FileWriter(this.destFileName); // <== Main logic
BufferedWriter bw = new BufferedWriter(fw) // <== Main logic
) { // <== Main logic
String line; // <== Main logic
while ((line = br.readLine()) != null) { // <== Main logic
if (shouldIncludeLine(line)) { // <== Main logic
line = transformLine(line); // <== Main logic
bw.write(line); // <== Main logic
bw.newLine(); // <== Main logic
} // <== Main logic
} // <== Main logic
}
catch (FileNotFoundException fnfe) { // <== Error handling
// Couldn't find a file // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
catch (IOException ioe) { // <== Error handling
// I/O error // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
catch (Exception e) { // <== Error handling
// Something else went wrong // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
}

假设的类 Java 语言无一异常(exception):

// THIS IS FAKE, PSEUDO-JAVA
private Errors process() {
Reader fr = new FileReader(this.sourceFileName); // <== Main logic
if (fr == null) { // <== Error handling
return Errors.CantOpenSource; // <== Error handling
} // <== Error handling
BufferedReader br = new BufferedReader(fr); // <== Main logic

Writer fw = new FileWriter(this.destFileName); // <== Main logic
if (fw == null) { // <== Error handling
br.close(); // <== Error handling
return Errors.CantOpenDest; // <== Error handling
} // <== Error handling
BufferedWriter bw = new BufferedWriter(fw) // <== Main logic

String line; // <== Main logic
while ((line = br.readLine()) != IO.END_OF_FILE) { // <== Main logic
if (line == null) { // <== Error handling
br.close(); // <== Error handling
bw.close(); // <== Error handling
return Errors.CantRead; // <== Error handling
}
if (shouldIncludeLine(line)) { // <== Main logic
line = transformLine(line); // <== Main logic
if (bw.write(line) == -1 || bw.newLine() == -1) { // <== Main logic (plus some error handling)
br.close(); // <== Error handling
bw.close(); // <== Error handling
return Errors.CantWrite; // <== Error handling
}
}
}

bw.close();
br.close();
return Errors.Success;
}

注意事项:

  • 主要逻辑如何充斥着错误处理,使其更难阅读和遵循。
  • 任何可能具有某种故障模式的方法都需要特殊的“错误”返回值。我们必须向 process 添加一个,然后我们从 new FileReader 等检查 null,并从 read 和 write 检查 -1操作等

如果您有兴趣,这里是 Java 程序的完整版本与非 Java 程序的完整版本:

Java:

import java.io.*;

public class Example
{
private String sourceFileName;
private String destFileName;

public static void main (String[] args) throws java.lang.Exception
{
try {
new Example(args[0], args[1]).process();
}
catch (ArrayIndexOutOfBoundsException npe) {
// This is a bit of an exaggeration, I'd check in advance, since the user not
// supplying arguments isn't really an "exceptional" condition.
System.out.println("Usage: java Example [source file name] [dest file name]");
}
}

public Example(String src, String dest) {
// Similar, these checks would probably be assertions, but I'm making a point...
if (src == null || src.length() == 0) {
throw new IllegalArgumentException("src must be non-null and non-blank");
}
if (dest == null || dest.length() == 0) {
throw new IllegalArgumentException("dest must be non-null and non-blank");
}
this.sourceFileName = src;
this.destFileName = dest;
}

private void process() {
try ( // <== Main logic
Reader fr = new FileReader(this.sourceFileName); // <== Main logic
BufferedReader br = new BufferedReader(fr); // <== Main logic
Writer fw = new FileWriter(this.destFileName); // <== Main logic
BufferedWriter bw = new BufferedWriter(fw) // <== Main logic
) { // <== Main logic
String line; // <== Main logic
while ((line = br.readLine()) != null) { // <== Main logic
if (shouldIncludeLine(line)) { // <== Main logic
line = transformLine(line); // <== Main logic
bw.write(line); // <== Main logic
bw.newLine(); // <== Main logic
} // <== Main logic
} // <== Main logic
}
catch (FileNotFoundException fnfe) { // <== Error handling
// Couldn't find a file // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
catch (IOException ioe) { // <== Error handling
// I/O error // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
catch (Exception e) { // <== Error handling
// Something else went wrong // <== Error handling
// (handle it) // <== Error handling
} // <== Error handling
}

private boolean shouldIncludeLine(String line) {
return line.length() != 0;
}

private String transformLine(String line) {
return line.toUpperCase();
}
}

假设的类 Java 语言无一异常(exception):

// THIS IS FAKE, PSEUDO-JAVA WITHOUT EXCEPTIONS, IT ISN'T REAL
import java.io.*;

public class Example
{
private String sourceFileName;
private String destFileName;

private enum Errors {
Success,
CantOpenSource,
CantOpenDest,
CantRead,
CantWrite
}

public static void main (String[] args) throws java.lang.Exception
{
if (args.length < 2) {
System.out.println("Usage: java Example [source file name] [dest file name]");
}
if (args[0] == null || args[0].length() == 0) {
throw new IllegalArgumentException("src must be non-null and non-blank");
}
if (args[1] == null || args[1].length() == 0) {
throw new IllegalArgumentException("dest must be non-null and non-blank");
}
switch (new Example(args[0], args[1]).process()) {
case Errors.CantOpenSource:
// Handle it
break;
case Errors.CantOpenDest:
// Handle it
break;
case Errors.CantRead:
// Handle it
break;
case Errors.CantWrite:
// Handle it
break;
}
}

public Example(String src, String dest) {
// Not how now this constructor is trusting that it is called with valid arguments
this.sourceFileName = src;
this.destFileName = dest;
}

private Errors process() {
Reader fr = new FileReader(this.sourceFileName); // <== Main logic
if (fr == null) { // <== Error handling
return Errors.CantOpenSource; // <== Error handling
} // <== Error handling
BufferedReader br = new BufferedReader(fr); // <== Main logic

Writer fw = new FileWriter(this.destFileName); // <== Main logic
if (fw == null) { // <== Error handling
br.close(); // <== Error handling
return Errors.CantOpenDest; // <== Error handling
} // <== Error handling
BufferedWriter bw = new BufferedWriter(fw) // <== Main logic

String line; // <== Main logic
while ((line = br.readLine()) != IO.END_OF_FILE) { // <== Main logic
if (line == null) { // <== Error handling
br.close(); // <== Error handling
bw.close(); // <== Error handling
return Errors.CantRead; // <== Error handling
}
if (shouldIncludeLine(line)) { // <== Main logic
line = transformLine(line); // <== Main logic
if (bw.write(line) == -1 || bw.newLine() == -1) { // <== Main logic (plus some error handling)
br.close(); // <== Error handling
bw.close(); // <== Error handling
return Errors.CantWrite; // <== Error handling
}
}
}

bw.close();
br.close();
return Errors.Success;
}

private boolean shouldIncludeLine(String line) {
return line.length() != 0;
}

private String transformLine(String line) {
return line.toUpperCase();
}
}

关于java - 为什么要在 Java 中使用异常处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34659328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com