繁体   English   中英

局部变量由于初始化时捕获异常而无法定义为最终变量

[英]local variable cannot be defined as final due to catching exception while initializing it

我通常喜欢将局部变量声明为final,但是我看到重复的模式,当我必须在初始化期间处理异常时无法执行此操作。

对于前我有这段代码:

final Client myClient = library.getClient("service");
//do a bunch of steps with myClient

但是我最终经常像这样修改它:

Client myClient = null;
try {
    myClient = library.getClient("service");
} catch (someException ex) {
    // handle
    throw ex;
}
// do stuff with myClient

在我完成所有工作之后,我不想添加捕获,因为随着即将结束,它变得有点难以理解。 那么,有没有更好的方法呢?

您可以将try / catch放在单独的方法中:

. . .
    final Client myClient = getClient();

private Client getClient() {
    try {
        return library.getClient("service");
    catch (someException ex) {
        // handle
        return null;
    }
}

如果在调用getClient()的方法中继续进行处理没有意义,那么另一种选择是声明它引发异常并摆脱try / catch块。

将代码放入构造函数中:

final Client myClient;

public MyClass() throws SomeException {
    myClient = library.getClient("service");
}

对于特定情况,您可以使用空白的final

final Client myClient;  // Note the lack of initialization here!
try {
    myClient = library.getClient("service");
} catch (someException ex) {
    // handle
    throw ex;
}
// do stuff with myClient

您不必在声明最终变量时就对其进行初始化,只要在可能最终使用它的每个代码路径上对它进行了一次初始化即可。

仅当catch块终止该方法(通过return或另一个throw )时,此方法才有效-您无法将其他后备值分配给myClient ,因为它可能已经在try块中分配了,这违反了单一初始化规则。

空白的final还可用于根据条件以不同的方式初始化某些东西:

final Client myClient;
if (someCondition) {
    myClient = foo();
}
else {
    myClient = bar();
}
// do stuff with myClient

当然,至少有两个简单的选择:

  • 您可以包装RuntimeException并确定何时/是否要处理它。
  • 您可以适当地重构,并将异常处理移出主线代码。

两者都有优点和缺点。

您可以在方法中拆分代码的不同部分,并将myClient作为最终变量移交...您还可以将所有代码添加到一个try catch块中,并抛出并处理不同的异常。 如果您不需要在异常部分使用var,这是有可能的...全局vars也可以是一种解决方案,但不是一个很好的解决方案。 如果无法阅读代码,则将其拆分为方法和类

作为包装getClient代码(在其他地方提到)的替代方法,可以包装doStuff代码:

try {
    doStuff( library.getClient("service") );
} catch (someException ex) {
    // handle
    throw ex;
}

public void doStuff(final Client myClient) {
    // do stuff
}

或者,您可以将两种方法结合起来:

try {
    doStuff( getClient() );
} catch (someException ex) {
    // handle
    throw ex;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM