简体   繁体   English

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

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

I usually like to declare my local variables as final but I see repeating patterns where I cannot do this when I have to handle an exception during its initialization. 我通常喜欢将局部变量声明为final,但是我看到重复的模式,当我必须在初始化期间处理异常时无法执行此操作。

For ex I have this code: 对于前我有这段代码:

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

But I end up modifying it very often like this: 但是我最终经常像这样修改它:

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

I do not want to add the catch after I do all the stuff as it becomes a bit unreadable as it is towards the end. 在我完成所有工作之后,我不想添加捕获,因为随着即将结束,它变得有点难以理解。 So is there a better way to do this? 那么,有没有更好的方法呢?

You can put the try/catch in a separate method: 您可以将try / catch放在单独的方法中:

. . .
    final Client myClient = getClient();

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

If it doesn't make sense for the processing to continue in the method that calls getClient() , then the other option is to declare it to throw the exception and get rid of the try/catch block. 如果在调用getClient()的方法中继续进行处理没有意义,那么另一种选择是声明它引发异常并摆脱try / catch块。

Put the code in the constructor: 将代码放入构造函数中:

final Client myClient;

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

For that particular case, you can use a blank final : 对于特定情况,您可以使用空白的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

You don't have to initialize a final variable when you declare it, as long as it's initialized exactly once on each code path where it might end up being used. 您不必在声明最终变量时就对其进行初始化,只要在可能最终使用它的每个代码路径上对它进行了一次初始化即可。

This only works if your catch block terminates the method (via return or another throw ) — you can't assign some other fallback value to myClient , because it might've been assigned in the try block already, violating the single-initialization rule. 仅当catch块终止该方法(通过return或另一个throw )时,此方法才有效-您无法将其他后备值分配给myClient ,因为它可能已经在try块中分配了,这违反了单一初始化规则。

Blank finals are also useful for initializing something in different ways depending on a condition: 空白的final还可用于根据条件以不同的方式初始化某些东西:

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

Sure, there are at least two trivial options: 当然,至少有两个简单的选择:

  • You can wrap in RuntimeException s and decide when/if you want to handle it. 您可以包装RuntimeException并确定何时/是否要处理它。
  • You can refactor appropriately and move exception handling out of the mainline code. 您可以适当地重构,并将异常处理移出主线代码。

Both have advantages and disadvantages. 两者都有优点和缺点。

you could split the different parts of your code in methods and hand over the myClient as a final var... you could also add all the code in one try an catch block and throw and handle different exceptions. 您可以在方法中拆分代码的不同部分,并将myClient作为最终变量移交...您还可以将所有代码添加到一个try catch块中,并抛出并处理不同的异常。 this is just possible, if you do not need the var in the exception-part... global vars could be also a solution, but not a nice one... there is a ground role. 如果您不需要在异常部分使用var,这是有可能的...全局vars也可以是一种解决方案,但不是一个很好的解决方案。 if you can't read your code, split it in methods and classes 如果无法阅读代码,则将其拆分为方法和类

As an alternative to wrapping the getClient code (mentioned elsewhere), you can wrap the doStuff code: 作为包装getClient代码(在其他地方提到)的替代方法,可以包装doStuff代码:

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

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

Or you could combine both approaches: 或者,您可以将两种方法结合起来:

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

暂无
暂无

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

相关问题 在初始化静态最终变量时捕获异常 - Catch exception while initializing static final variable 无法分配最终的局部变量,因为它是在封闭类型中定义的 - The final local variable cannot be assigned, since it is defined in an enclosing type 无法分配最终的局部变量标记,因为它是在封闭类型中定义的 - The final local variable token cannot be assigned, since it is defined in an enclosing type 最终局部变量无法分配,因为它是在封闭类型中定义的 - The final local variable cannot be assigned, since it is defined in an enclosed type 最终局部变量无法分配,因为它是在封闭类型java中定义的 - The final local variable cannot be assigned, since it is defined in an enclosing type java 最终的局部变量 dc 无法赋值,因为它是在封闭类型中定义的 - The final local variable dc cannot be assigned, since it is defined in an enclosing type Java:最终的局部变量无法分配,因为它是用封闭类型定义的 - Java: the final local variable cannot be assigned, since it was defined in an enclosing type 最终局部变量checkstate不能分配,因为它是用封闭类型定义的 - The final local variable checkstate cannot be assigned, since it is defined in an enclosing type 最终局部变量无法分配,因为它是用封闭类型定义的? - The final local variable cannot be assigned, since it is defined in an enclosing type? 无法分配最终的局部变量 - The final local variable cannot be assigned
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM