【问题标题】:Regarding try-catch关于try-catch
【发布时间】:2012-04-25 09:48:43
【问题描述】:

我目前正在学习 Java 入门课程,这是关于 try-catch 方法的。当我输入这个时,我的System.out.println 语句不断重复。这是我的代码:

public static double exp(double b, int c) {
    if (c == 0) {
        return 1;
    }

    // c > 0
    if (c % 2 == 0) {
        return exp(b*b, c / 2);
    }
    if (c<0){
        try{
        throw new ArithmeticException();
        }
        catch (ArithmeticException e) {
            System.out.println("yadonegoofed");
        }
    }

    // c is odd and > 0
    return b * exp(b, c-1);
}

【问题讨论】:

  • 您实际上并没有在这里提出问题。请展开:-)
  • 除了特定的问题:抛出异常并立即捕获它并不是很好地使用异常。

标签: java exception-handling if-statement try-catch throw


【解决方案1】:

在创建自己的自定义异常时,您忘记了一个非常重要的部分。你忘了告诉方法它会抛出这样的方法。 您的第一行代码应如下所示:

public static double exp(double b, int c) throws ArithmeticException {

请注意,我自己对此进行了测试,它只会在您的输出中抛出一次异常。

【讨论】:

  • 这个方法也捕获了异常——它不能离开函数。不过,一旦问题得到解决,这是一个很好的观点。 :)
【解决方案2】:
if (c<0){
    try{
    throw new ArithmeticException();
    }
    catch (ArithmeticException e) {
        System.out.println("yadonegoofed");
    }
}

// c is odd and > 0
return b * exp(b, c-1);

您的评论 c is odd and &gt; 0 不正确——您从未真正终止该函数,但有异常。你扔了它,你立即接住它,然后继续执行递归函数。最终,当您点击wraparound 时,它将再次变为正数,并且不会发生错误。 (大约需要 20 亿次迭代——别等了。)

我不会在这里使用异常——你只需要终止递归。我会在检查0之前检查负输入,然后在那里抛出异常,然后在调用者中捕获异常

在伪代码中:

exp(double b, int c) {
    if (c < 0)
        throw new Exception("C cannot be negative");
    } else if (c % 2 == 0) {
        return exp(b*b, c / 2);
    } else {
        /* and so forth */
    }
}

【讨论】:

  • 你解释得比我在下面做的要好得多。公平地说,如果 c 为负数确实是一种异常情况(即 c 永远不应该
  • @James:同意,立即捕获异常是非常奇怪的。我以前曾见过用于退出深度嵌套循环的异常,但对于一个方法来说,捕获它抛出的异常是一种奇怪的做法。
  • 回头看代码,它只对正整数有效,所以抛出是有意义的,但它肯定是传播它,而不是捕获。
  • 在那里使用仍然很奇怪。我认为带标签的 continue 会更合适。
  • 我认为抛出异常是公平的游戏——因为这个函数只对非负输入有效,任何使用非负输入调用它的调用者,根据定义,都会被破坏。跨度>
【解决方案3】:

您的 BASE 案例非常具体...在您的代码中保证 c 等于 0 的内容是什么?目前,这是您退出递归调用的唯一方式。正如@Jay 所说,您总是减去 1 会导致抛出异常,但此时 c 已经低于 0,因此它不等于 0。将您的第一个 if 语句更改为捕获值

if( c <= 0 )
     return 1;

【讨论】:

  • 虽然我认为你打得很好,但c &lt; 0 的情况可能是一个错误,应该作为错误处理。
  • @sarnold 虽然这可能是真的。没有实际的问题,所以每个人都只是猜测预期的结果是什么......他似乎唯一提到的是一个问题是 sys.out 总是打印。我只是简单地说明了一种解决方法。同样,根据给出的信息,我们任何人都可以做的就是推测。
【解决方案4】:

例如,如果 c = -1 in,第一个和第二个 if 失败,第三个 if 抛出异常,然后打印错误,但事情进展,因为您处理了异常。所以它调用 exp(b, -2)。反过来,它在返回中调用 exp(b, -3),依此类推。将 C 的值添加到您的 println 以进行验证。

【讨论】:

  • 我特别喜欢这个建议将 C 的值添加到您的println 以进行验证。。这将非常很快地指出问题。 :)
  • @sarnold - 我抛出异常的一般原则 - 如果它确实是一个异常情况,并且你无法从消息中判断它为什么是异常的,那么你做错了:)
【解决方案5】:

好吧,最后你有return b * exp(b, c-1);,这将再次调用exp,它将再次调用它。
所以函数会不断重复,所以也会 System.out.println.

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多