java - 如何使用 System.exit 避免 try/catch 附近的 "variable might not have been initialized"

标签 java

我想避免这种丑陋的模式:

Long foo = null;
Double bar = null;

try {
  foo = Long.parseLong(args[0]);
  bar = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
  System.out.println(USAGE);
  System.exit(1);
}

doSomethingWith(foo, bar);

知道我可以将初始化和doSomethingWith移动到try block 中,但想象一下:

  • doSomethingWith 实际上是几行条件逻辑,很多方法调用、语句等。
  • 我不想将 block 嵌套得过深
  • 我想避免意外捕获 doSomethingWith 抛出的意外 NumberFormatException

我发现 = null 及以上内容非常难看,并且使用类而不是基元。这种丑陋让我怀疑有更好的方法来编写这段代码。

我的第一个愿景当然是

long foo;
double bar;

try {
  foo = Long.parseLong(args[0]);
  bar = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
  System.out.println(USAGE);
  System.exit(1);
}

doSomethingWith(foo, bar);

但我们都知道,当您尝试构建变量时,Java 会抛出几个变量可能未初始化错误。

针对此类问题有什么更好的设计模式? “更好”的意思(对我来说)做到了这一切

  • 避免奇怪的= null
  • 避免对基元进行不必要的类包装
  • 不会深入嵌套到 try block 中
  • 不会捕获/隐藏不该捕获的异常

如果这是不可能的,或者如果我的“漂亮”代码概念是错误的,请说服我并展示当前可以使用的最佳代码。

最佳答案

这里的奇怪之处在于编译器不知道System.exit(1);永远不会返回。如果它知道这一点,它会很高兴。

所以你需要做的就是给它一些它知道不会让你从catch block 到达try/catch之后的东西。例如:

try {
  foo = Long.parseLong(args[0]);
  bar = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
  System.out.println(USAGE);
  System.exit(1);
  throw new RuntimeError("Make sure the end of the catch block is unreachable");
}

如果您需要经常这样做,您可能需要编写一个辅助方法,并抛出它的结果(您永远不会使用它)。这样,您仍然只有一行代码来表示“我想立即退出”。

try {
  foo = Long.parseLong(args[0]);
  bar = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
  System.out.println(USAGE);
  throw HelperClass.systemExit(1);
}

...

public class HelperClass {
  public static RuntimeException systemExit(int exitCode) {
    System.exit(1);
    throw new RuntimeException("We won't get here");
  }
}

我经常使用的另一个选项是定义一种“用户错误”异常。然后,您可以在顶层(在 main 中)捕获该信息,打印任何消息并可能显示用法。这样:

  • 您可以对用户错误进行单元测试(单元测试 System.exit 至少更尴尬)
  • 您可以集中处理“如果用户犯了错误,我想做什么”,而不是在多个位置包含 System.out.println(USAGE)
  • 您不会遇到这种明确的分配问题

所以你的代码将是:

try {
  foo = Long.parseLong(args[0]);
  bar = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
  throw new UserInputException("foo and bar must both be valid integers");
}

关于java - 如何使用 System.exit 避免 try/catch 附近的 "variable might not have been initialized",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59200218/

相关文章:

java - Ivy 无法解析依赖关系的范围,该依赖关系是传递依赖关系的依赖关系

java - 如何使用 Sjeda 替换 PDF 中的文本?

java - 无法将对象转换为实体类型

java - groovy 和 lombok @Value 中的命名参数构造函数

java - LibGdx - 默认代码的 NullPointerException

java - jsf中可以显示的行数限制

java - 如何在大型遗留项目中将 String id 重构为 class Id?

java - ehcache 在 Tomcat Docker 镜像中不工作

java - @Valid 失败时自动返回输入表单

java - 如何在 RecyclerView Adapter 中使用架构组件 ViewModel?