重试代码块后抛出异常

时间:2016-04-20 02:54:43

标签: java

成功重试后抛出异常是否正确,安全且理智?在这个例子中违反了哪种编程原理?

class B {
    private int total;

    public void add(int amount) throws Exception {
        if (amount < 0) {
            throw new Exception("Amount is negative");
        }
        total += amount;
    }
}

class A {
    public B b = new B();

    public void addToB(int amount) throws Exception {
        try {
            b.add(amount);
        } catch (Exception ex) {
            try {
                b.add(-amount);
            } catch (Exception ex2) {
            }
            throw new Exception("Amount was negative. It was inverted and then added.");
        }

    }
}

3 个答案:

答案 0 :(得分:2)

您的code正在运作,但由于您在addToB() method内呼叫throws exception catch block,您必须实施另一个try-catch block within try-catch block。最后你throwing a exception即使有这么多try-catch blocks这是不好的,因为exceptions如果不处理会导致problems及其非常糟糕practise如果方法为throw exception,则转至success。我发现您需要用户知道method内发生了什么,您可以return string来自inside the method 将告诉用户发生了什么的方法public String addToB(int amount){ String msg = ""; try{ b.add(amount); msg ="successful"; }catch(Exception ex){ try{ b.add(-amount); }catch(Exception ex2){ } msg= "Amount was negative. It was inverted and then added."; } return msg; }

前: -

<paper-icon-button>

即使这不是您可能需要检查的最佳做法。

答案 1 :(得分:2)

您违反了一些合理的原则。

  1. 即使您正在编写玩具代码,在这种情况下(或一般情况下)投掷java.lang.Exception也是不好的。您应该考虑使用RuntimeException。这个想法非常简单。在运行程序之前,您对amt一无所知。如果此代码的用户或客户端提供否定参数,那么它只是在运行时才知道的意外参数。不要宣传Pokemon exception handling anti-pattern

  2. 您正在使用baklava code模式。应该避免这种情况。

  3. 你提出的更严重的错误是无论如何都要特别做或不做。这是你的课程的用法:

    public static void main(String[] args) {
        A a = null;
        try {
            a = new A();
            a.addToB(10); // no exception here, total should be 10
            a.addToB(-10); 
        } catch (Exception e) {
            // exception here, but the total should be 20, or not?
            System.out.println(a.getTotalFromB());
        }
    }
    

    现在,在这种情况下,即使抛出异常,total的值也是20 !几乎总是,应该使用异常来表示预期事情没有发生的异常情况。对我来说,这是一个严重的违规行为。

答案 2 :(得分:2)

可能这样做,但这有三个原因:

  • 您正在使用exceptions as control flow。这是一个应该避免的反模式。
  • 你在扔Exception。如果这是非常特殊的行为,那么您应该创建自己的[checked]异常类型。
  • 您在该区块中捕捉 Exception。如果bnull,那么您无法保证输入完全无效。

让我们从流程开始。

在这种情况下,为什么负值被认为足以超出 recover ,这就是检查异常所暗示的内容。

实际上,如果第一次尝试似乎失败并带有负数,那么我们的想法是通过否定负数来再次尝试,从而产生正数。

这样的事情可以通过多种方式得到缓解,具体取决于负面价值对企业的意义:

  • 投掷多个例外(最不喜欢)
  • 默默地删除它,但记录传入的值(不太喜欢)
  • 抛出未经检查的例外,并且不要求其调用者捕获它(首选)

根据我的偏好,上面的代码如下所示:

public void add(int amount) {
    if(amount < 0)
        throw new IllegalArgumentException("Amount may not be negative");
    total += amount;
}

这将使得在开发人员而不是应用程序上确保输入正确且适合此方法的责任。这里的单元测试将大大有助于确保您想要的行为。

现在,抛出ExceptionException 已检查,这意味着每个人都必须抓住它或声明它被抛出,这对代码来说是不愉快的。

应为用户可以恢复的内容保留已检查的异常(例如,FileNotFoundException - 用户应确保文件路径正确。)

最后 - 您应该抓住Exception。考虑到b可能是null,这是一个过于宽泛的例外。