繁体   English   中英

我断言 Java 中不会发生错误。 我该如何编码?

[英]I assert an error cannot happen in Java. How do I code that?

这是我的代码:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
  outputStream.write(signature.getR());
  outputStream.write(signature.getS());
  outputStream.write(signature.getV());
} catch (java.io.IOException exception) {
  // WHAT GOES HERE?      
}

Java 文档告诉我这个ByteArrayOutputStream可能会抛出一个IOException 所以编译器要求我把它放在一个try / catch块中。

基于我只连接大约 100 个字节的事实,同时我没有关闭 stream,我预计不会出现任何错误。

或者更清楚地说,我不想处理或传递任何错误。

在 Swift 中,我会使用断言( try! )来做到这一点。

在 Java 中,我该如何做到这一点,以便此处的异常导致程序终止并且不需要我在整个过程中冒泡异常?

无效/不一致/意外场景

  1. Checked Exceptions - 预期和调用者应该知道(运行时课程更正)
  2. 未经检查的异常 - 意外且调用者无需进行课程更正(返回编码、修复和重新部署)

检查异常

  1. 可能无效的 state 操作,其中直接调用者可以进行课程更正
  2. 或者通过添加到throws在调用层次结构中向上传播此类异常
  3. 或者变成一个未经检查的异常,因为这是一个不可接受的 state 由于错误并决定调用者的决定
  4. 默默地消费(捕捉)并继续进行,就好像什么都没发生一样

为什么 IO 操作一般都会被Checked

  1. IO(网络)可能暂时不可用,以便调用者可以重试
  2. IO(文件)权限可能不正确,因此调用者可以尝试替代操作(如果允许,则使用不同的路径或更改权限)
  3. 资源(空间)不足,调用者可以释放一些资源并重试
  4. 路径无效,因此写入不同的路径(或创建路径)

未经检查的异常

  1. 运行时不应发生的无效状态(例如 NPE)
  2. 意外状态,如堆栈溢出错误、超出 memory 错误(尽管调用者可以通过采取替代操作(如取消引用 GC 大对象或调用迭代逻辑而不是递归逻辑)来纠正)。 这些动作应该由开发者在编译时决定,一般不应该在运行时处理。

Java 状态

  1. Throwable - 任何无效的 state - 未选中
  2. 异常 - 主要预测无效状态(RuntimeException 也无法预测) - 检查除 RuntimeException 层次结构之外的所有人
  3. RuntimeException - 一种特殊类型的异常,用于不可预测或不应该发生或别无选择 - 未选中
  4. 错误 - 异常且无法处理 - 未选中

假设调用是针对write(int)的,则可以安全地忽略此特定用例

ByteArrayOutputStream.write(int) 不会抛出已检查异常没有为.write(int) Doc定义已检查异常

但父 class OutputStream已检查异常。

因此,除非您使用 OutStream 作为引用来保存 ByteArrayOutputStream object,否则catch块可以留空或什至不需要

以下代码在 JDK 11 编译器和运行时中运行良好

    public static void main(String[] args) {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        b.write(65);
        System.out.println(b.toString());
    }

它可以为 null 输入抛出 NPE(技术上这是拆箱错误)

    public static void main(String[] args) {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        Integer input = null;
        b.write(input);
        System.out.println(b.toString());
    }

如果它的 write(byte[]),那么OutputStream.write会抛出检查异常,因此它必须被捕获。

但它也可以抛出其他运行时异常。

    public static void main(String[] args) {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        try {
            b.write((byte[])null); // NPE
        } catch (IOException e) {
            System.out.println(e);
        } catch (RuntimeException e) {
            System.out.println(e);
        }
    }
catch (java.io.IOException exception) {
  throw new UncheckedIOException(exception);     
}

在 Java 8 中引入UncheckedIOException的原因之一是为了隐藏 Java 中对IOException的滥用,并关闭编译器。 对于不能抛出检查异常的 lambdas 非常有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM