【问题标题】:Try...catch vs if...else for exceptions - JavaTry...catch vs if...else 异常 - Java
【发布时间】:2012-06-29 09:38:47
【问题描述】:

如果我想从 args[0] 数组中获取用户输入,但万一我(用户)忘记定义它,我想要一个提示 - 使用 if 块更好吗确定数组项是否为空,或捕获异常?那么,这是

public class Stuff {
    static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        String foo;
        if(args.length > 0) {
            foo = args[0];
        }
        else {
            foo = getString("Input? ");
        }
    }
    public static String getString(String prompt) {
        System.out.print(prompt + " ");
        String answer = input.nextLine();
        return answer;
    }   
}

更好或更差

public class Stuff {
    static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        String foo;
        try {
            foo = args[0];
        }
        catch(ArrayIndexOutOfBoundsException e) {
            foo = getString("Input? ");
        }
    }
    public static String getString(String prompt) {
        System.out.print(prompt + " ");
        String answer = input.nextLine();
        return answer;
    }   
}

【问题讨论】:

  • 行为不一样。 if 示例仍然会抛出 ArrayOutOfBoundException,因为您正在尝试访问 args[0]。您应该使用 args.length 来检查数组是否为空,然后检查数组的第一个元素是否为空。
  • “if 示例仍然会抛出 ArrayOutOfBoundException,因为您正在尝试访问 args[0]。” OP 已将数组检查更改为 if(args.length > 0) {。原来的问题仍然存在。哪个结构更好? if-else 还是 try-catch?以何种方式更好,为什么?

标签: java if-statement try-catch


【解决方案1】:

您的第一个示例仍将引发异常,因为在 if 语句中您仍在访问不存在的索引。

如果您想使用 if 语句,那么您应该检查数组的长度是否大于您尝试访问的索引,例如:

if(args.length > 0)
    foo = args[0];

【讨论】:

  • 原问题已修改..这可能不再有效。
【解决方案2】:

你需要测试args.length而不是阅读args[0]

但除了那个错误,最好使用if/else,原因如下:

  • 让代码更清晰
  • 它具有更好的性能(尽管在这种情况下不相关)
  • 没有异常情况(预计 args 数组在某些情况下可能为空,例如“用户错误”,因此代码应该能够处理它)。应该为不应该发生的异常情况保留异常抛出。

【讨论】:

  • 还有side effects的问题。当代码被“尝试”时,它可能会更改程序或数据的状态——如果某个条件会导致抛出异常,则不应发生这种更改。使用if-else 将避免副作用,因为如果给定条件当前为假,它将跳过整个代码 - 从而提高数据完整性。
【解决方案3】:

IMO,if-else 在这种情况下更好/更快。

当你在一个方法中并且你想告诉调用者出错了,而你不能用返回值来做时,就会使用抛出异常。

但正如 Jon Taylor 所说,你的 if 语句不会那样工作。

【讨论】:

    【解决方案4】:

    您真正需要的只是一行代码。

    final String foo = args.length > 0? args[0] : getString("Input? ");
    

    【讨论】:

    • 我同意,虽然很多人讨厌这种说法,但我个人喜欢他们,但很多人不喜欢。它也没有真正回答这个问题。或者至少它没有解释为什么你改变了他的 if 语句。
    • @JonTaylor OP 已经为您和其他答案提供了很好的服务。这是一种补充。
    • True :),我很喜欢这种说法,对我来说它非常清晰简洁。老实说,我希望更多人使用它们。
    • @JonTaylor 对我来说最重要的功能是它类似于 FP。自从 Clojure 成为我的主要语言以来,我尽可能使用它,即使是在更复杂的组合中(比如模拟一个 lisp cond 而不是 if-else if-else if 和类似的)。
    【解决方案5】:

    使用 if 块判断数组是否为空,方便快捷。

    【讨论】:

    • 这没关系,但如果他们决定访问元素 1 而不是 0,则检查它是 empy 是不够的。检查长度是否大于索引。
    • 我不确定常见情况下的“更快”,即当数组元素存在时。我相信至少有一些实现,其中 try 块没有性能影响,并且当异常实际发生时,所有工作都在堆栈展开器中完成,因此常见情况下使用较少的分支指令。由于在上述情况下性能不应该很重要,因此这不是主要问题,但总体上值得考虑。
    【解决方案6】:

    鉴于 Jon Taylor 证明的更正,我更喜欢带有 if 的版本。

    不仅是为了提高速度(在你的示例中我猜这不会明显),而且因为带有 if 的代码更好地解释了它的意图,简化了代码的未来维护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多