gpt4 book ai didi

java - 在 Java 中生成 fatal error

转载 作者:搜寻专家 更新时间:2023-10-31 08:23:02 24 4
gpt4 key购买 nike

假设我们正在编写一个 Java 库,它提供了一些 I/O 实用函数,例如,一种将文本文件读取为字符串的便捷方法:

public class StringReader {

private static final Logger log = LoggerFactory.getLog(StringReader.class);

/**
* Returns the contents of file <b>fileName</b> as String.
* @param fileName file name to read
* @return null on IO error
*/
public static String readString(String fileName) {
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
byte[] data = new byte[fis.available()];
fis.read(data);
return new String(data, "ISO-8859-1"); // may throw UnsupportedEncodingException!
} catch (IOException e) {
log.error("unable to read file", e);
} catch (UnsupportedEncodingException e) {
log.fatal("JRE does not support ISO-8859-1!", e);
// ???
} finally {
closeQuiet(fis);
}

return null;
}
}

此代码使用 ISO-8859-1 编码将文本文件读入字符串并将字符串返回给用户。

当不支持指定的编码时,String(byte[], String) 构造函数会抛出一个 UnsupportedEncodingException。但是,正如我们所知,JRE 必须支持 ISO-8859-1,如 here (see the Standard charsets section) 所述.

因此,我们期待区 block

catch (UnsupportedEncodingException e) {
log.fatal("encoding is unsupported", e);
// ???
}

如果 JRE 分发符合标准,则永远不会达到。

但如果没有呢?如何以最正确的方式处理这个异常?问题是,如何正确提醒此类错误?

建议是:

  1. 抛出某种RuntimeException
  2. 不要在生产代码中禁用记录器,在日志中写入异常详细信息并忽略它。
  3. assert false 放在这里,因此如果用户使用 -ea 启动 VM,它会产生 AssertionError。
  4. 手动抛出一个AssertionError
  5. 在方法声明中添加一个UnsupportedEncodingException 并允许用户选择。我觉得不是很方便。
  6. 调用 System.exit(1)

谢谢。

最佳答案

But what if it doesn't?

那么你的处境真的很糟糕,你应该尽快摆脱它。当 JRE 违背自己的 promise 时,您依赖什么?

在这种情况下,我很乐意使用 AssertionError

重要的是要注意并非所有未经检查的异常都被平等对待 - 代码在堆栈的顶层捕获 Exception 并记录错误然后继续...并不罕见...如果你只要抛出 RuntimeException就会被这种方案捕获。 AssertionError 只有在 catch block 指定了 Throwable(或者特别是 ErrorAssertionError 时才会被捕获,但这种情况要少得多查看)。鉴于这应该是多么不可能,我认为非常努力地中止是合理的。

另请注意,在 Java 7 中,您可以使用 StandardCharsets.ISO_8859_1 代替字符串名称,这样更简洁并消除了问题。

顺便说一句,我还想对您的代码进行其他更改:

  • 我会尽可能避免使用 available()。这会告诉您现在有多少字节可用 - 但不一定会告诉您文件的长度。
  • 绝对不会假设read() 会一次读取整个文件。在循环中调用 read(),理想情况下,直到它说没有更多数据为止。
  • 我个人会接受 Charset 作为参数,而不是硬编码 ISO-8859-1。 - 我会让 IOException 从方法中冒出来,而不是只返回 null。毕竟,除非您真的要检查每个调用的返回值是否为 null,否则您只会以 NullPointerException 结束,这更难诊断比原始 IOException

或者,只需使用 GuavaFiles.toString(File, Charset)从 :) 开始(如果您还没有使用 Guava,现在是开始的好时机...)

关于java - 在 Java 中生成 fatal error ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19651681/

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