有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java什么是流控制异常的替代方案?

我继承了一个java应用程序,该应用程序处理请求,并在确定应取消请求时抛出异常。对于以前的开发人员来说,异常很方便,因为它们是一种退出不再适用的逻辑树的简单方法(是的,是goto),并且它会将堆栈跟踪打印到日志中,这是一个很好的信息。论坛和博客上的共识似乎是,例外不应用于流量控制,处理的请求中有一半以上被取消,因此它们肯定不是例外情况。一个理由是性能,这不适用,因为我们的异常代码已经运行了很多年了。另一个论点是,它的目的不明确,我同意。我的问题是:替代方案是什么。我能想到的唯一一件事是,如果处理应该继续,让每个方法都返回true;如果处理不应该继续,则返回false。这似乎会极大地增加我的代码,改变这一点:

checkSomething();
checkSomethingElse();

对此:

boolean continueProcessing = false;
continueProcessing = checkSomething();
if (!continueProcessing) {
    return false;
}
continueProcessing = checkSomethingElse();
if (!continueProcessing) {
    return false;
}

那么如果这个方法应该返回什么呢?任何指导都很好。我真的很想观察任何可用的“最佳实践”

更新:

我可能应该首先提到的另一点是,一个请求在50%以上的时间里被取消,这并不意味着某件事不顺利,这意味着该请求根本不需要


共 (5) 个答案

  1. # 1 楼答案

    int error = 0;
    
    do
    {//try-alt
        error = operation_1(); if(error > 0){break;}
        error = operation_2(); if(error > 0){break;}
        error = operation_3(); if(error > 0){break;}
    }while(false);
    
    switch(error) //catch-alt
    {
     case 1: handle(1); break;
     case 2: handle(2); break;
     case 3: handle(3); break;   
    }
    
  2. # 3 楼答案

    怎么样

    if (!checkSomething()) return false;
    if (!checkSomethingElse()) return false;
    

    如果你提前退出,就不需要挂国旗

  3. # 4 楼答案

    在您的场景中,替代方案是抛出异常并返回结果

    哪个是最好的(哪个是“最佳实践”)取决于“检查”失败方法应分为正常或例外。在某种程度上,这是你必须做出的判断。在打电话时,有几件事需要记住:

    • 创建+抛出+捕获异常大约比测试布尔结果慢3个数量级

    • 返回状态码的最大问题是很容易忘记测试它们

    总之,最佳实践是不使用异常来实现正常流控制,但由您决定正常异常之间的边界在哪里


    在没有看到真正的代码/上下文的情况下,我的直觉是,这可能是一个使用异常的合适地方

  4. # 5 楼答案

    tl;博士

    分离关注点,在我看来,你应该这样做:

    continue = checkSomething() && checkSomethingElse();
    

    或者代码中还有其他设计问题



    当你想要定义函数时,函数的关注点是什么(这可能是一个主观问题)如果错误符合函数的考虑,那么不要抛出异常。如果您对错误是否符合关注点感到困惑,那么可能函数试图自己完成太多关注点(糟糕的设计)

    错误控制选项:

    1. 不要报告错误。它要么直接由函数处理,要么就无关紧要了
    2. 返回值为
      1. null而不是对象
      2. 错误信息(甚至可能是与成功返回的对象不同的数据类型)
    3. 传入的参数将用于存储错误数据
    4. 触发事件
    5. 如果发生错误,调用传递给函数的闭包
    6. 抛出一个异常。(我认为这通常只应该在它不是任意定义的函数目的的一部分时进行)

    如果代码的目的是检查某个状态,那么知道该状态为false直接是函数的点。不要抛出异常,但返回false

    这就是你想要的。进程X正在运行检查程序Y和Z。进程X(或任何调用进程)的控制流与检查系统状态的关注点不同