在 Java 中,通过函数调用将运行时异常用作超级"break"是不好的做法吗?



有时,会有一系列函数调用,在中间确定结果,并希望中途停止整个函数链。在这种情况下,下面的方式不好吗?

public ResponseObject composeResponse {
try {
ResponseObject response = new ResponseObject();
processA(response);
processB(response);
processC(response);
processD(response);
.
.
.
return response;
} catch (SomeFlagException e){
return response;        
}
}

其中,对于每个过程函数,它也类似于

public void processA(ResponseObject response){
minorProcess1(response);
minorProcess2(response);
minorProcess3(response);
.
.
.
}

在某些特定的条件下,比如minorProcess3((,会出现这样的情况,即结果已确定,而不需要其他进程。假设这种情况发生在许多minorProcesses中。

public void minorProcess3(ResponseObject response){
//some process
if (someFlag){
//want end the process and return the result
throw new SomeFlagException(); //SomeFlagException extends RuntimeException
}
}

我的头脑在告诉我不,因为这不是一个"不";异常";但这是一个可期待的结果。我听说只有在无法合理解决异常时,才应该抛出未检查的异常。但我只能想出这种方法来清理代码,否则代码将不得不将条件检查级联到基函数。

编辑:添加关于我的情况的信息。这是一个web项目,因此它假设返回带有有效负载的正确响应。有时,请求应该通过204/40x进行响应。不需要有效载荷,因此不需要进一步的处理,应该放弃。

是的,这样做真的很糟糕。

例外情况意味着某些方法无法履行其合同。你所问的方法正好相反:用一个例外来表示早期成功。

尽管它在技术上是可行的,但它与异常的预期含义背道而驰,我不得不强烈建议不要使用这种方法。

我听说只有当它无法合理解决。

IMHO,这是个糟糕的建议。作为抛出异常的方法,您如何知道调用堆栈中的某个调用方方法在失败后是否能够成功继续?这只能在调用方的上下文中决定(是否有失败的后备策略(,很少取决于异常的类型。这不是你的责任,即使你试图做出这个决定,结果也很可能是错误的。

例如,对于您的呼叫者来说,您是因为NullPointerException还是IOException而失败通常无关紧要,仅举两个未检查/已检查类别的突出示例。重要的是,你失败了,也许打电话的人知道在你失败后如何继续。

作为算法逻辑的一部分,您不应该抛出异常。异常情况必须表明我们不希望出现错误的

一种更干净的方法是让process(ResponseObject)minorProcess(ResponseObject)方法返回一个boolean值,该值指示响应的过程是否应该继续。

参见示例:

public boolean processX(ResponseObject response)
{
boolean shouldContinue;
shouldContinue = shouldContinue && minorProcess1(response);
shouldContinue = shouldContinue && minorProcess2(response);
shouldContinue = shouldContinue && minorProcess3(response);
.
.
.
return shouldContinue;
}

使用&&运算符时,如果第一个条件为false,则不计算第二个条件。

minorProcess示例:

/**
*
*/
public boolean minorProcessX(ResponseObject response)
{
//some process
if (someFlag)
{
//want end the process and return the result
return false;
}
}

最新更新