这是滥用try/finally吗?

Dol*_*lph 32 java language-agnostic coding-style

鉴于多个返回语句是可接受的(我有点不同意,但让我们离题),我正在寻找一种更可接受的方式来实现以下行为:

选项A:多次返回,重复代码块

public bool myMethod() {
    /* ... code ... */

    if(thisCondition) {
        /* ... code that must run at end of method ... */
        return false;
    }

    /* ... more code ... */

    if(thatCondition) {
        /* ... the SAME code that must run at end of method ... */
        return false;
    }

    /* ... even more code ... */

    /* ... the SAME CODE AGAIN that must run at end of method ... */
    return lastCondition;
}
Run Code Online (Sandbox Code Playgroud)

每次方法返回时,看到相同(小)代码块重复三次会让我觉得很脏.此外,我想澄清一下,return false上面的两个陈述当然可以被描述为返回中间方法......它们绝对不是"守卫声明".

选项B 稍微可以接受吗?我觉得我可能会滥用尝试/最后,我希望我应该做的事情完全不同.

选项B:多次返回,try/finally块(没有catch块/异常)

public bool myMethod() {
    try {
        /* ... code ... */

        if(thisCondition) {
            return false;
        }

        /* ... more code ... */

        if(thatCondition) {
            return false;
        }

        /* ... even more code ... */

        return lastCondition;
    } finally {
        /* ... code that must run at end of method ... */
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,选项C是书中的最佳解决方案,但我的团队不管出于何种原因都不喜欢这种方法,因此我正在寻求妥协.

选项C:单一返回,条件块

public bool myMethod() {
    /* ... code ... */

    if(!thisCondition) {
        /* ... more code ... */
    }

    if(!thisCondition && !thatCondition) {
        /* ... even more code ... */
    }

    /* ... code that must run at end of method ... */
    return summaryCondition;
}
Run Code Online (Sandbox Code Playgroud)

如果您想讨论多个退货声明,请在此问题中进行讨论.

Joa*_*uer 30

如果代码需要运行,即使任何其他代码抛出异常,那么该finally块是正确的解决方案.

如果它不需要在异常的情况下运行(即它只需要"正常"返回),那么使用finally将滥用该功能.

我个人用单返回点样式重写该方法.不是因为我虔诚地赞同这个想法(我没有),而是因为它最适合这种方法结束的代码.

当该代码变得过于复杂时(这是非常现实的可能性),那么是时候通过提取一个或多个方法来重构该方法.

最简单的重构将是这样的:

public boolean  myMethod() {
    boolean result = myExtractedMethod();
    /* ... code that must run at end of method ... */
    return result;
}

protected boolean myExtractedMethod() {
    /* ... code ... */

    if(thisCondition) {
        return false;
    }

    /* ... more code ... */

    if(thatCondition) {
        return false;
    }

    /* ... even more code ... */
    return lastCondition;
}
Run Code Online (Sandbox Code Playgroud)


use*_*019 28

例外情况应该是例外的,所以如果周围没有其他例外情况,我不喜欢选项B(注意为downvoters - 我不是说最终不正确只是因为如果没有例外我不想拥有它 - 如果你有理由请评论)

如果总是需要代码,那么如何重构为2个函数

public bool myMethod() {
    bool summaryCondition = myMethodWork();
    // do common code
    return summaryCondition;
}

private bool myMethodWork() {
   /* ... code ... */

    if(thisCondition) {
        return false;
    }

    /* ... more code ... */

    if(thatCondition) {
        return false;
    }

    /* ... even more code ... */

    return lastCondition;
}
Run Code Online (Sandbox Code Playgroud)

  • +1正确回答问题的后半部分.但是,在没有例外情况下最终不正确的评论是完全错误的.try/finally存在是为了执行一些代码块,然后总是做一些其他事情而不管该块如何退出 - 最终通常与异常处理相关但不限于此; 终于使用退出处理也是完全合法的. (19认同)
  • 我同意@SoftwareMonkey; `finally`块独立于任何`catch`块.实际上,在Java代码中有太多的`try-catch`实例应该是`try-finally`.换句话说,当需要清理资源并让具有更多上下文的调用者处理异常时,通常会捕获异常并进行错误处理. (2认同)

Dav*_*ill 15

这是一个完美的地方 GOTO

*鸭子*

  • 我认为,并希望,大卫是认真的. (5认同)
  • @Loadmaster:在C++中,通常会使用类似"ScopeGuard"的东西来执行最后一段代码. (3认同)