我想避免这种丑陋的模式:
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/