2

我通常喜欢将我的局部变量声明为 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

我不想在我做完所有事情之后添加捕获,因为它在接近尾声时变得有点难以理解。那么有没有更好的方法来做到这一点?

4

6 回答 6

3

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

. . .
    final Client myClient = getClient();

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

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

于 2012-06-19T01:09:30.143 回答
1

对于这种特殊情况,您可以使用空白 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

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

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

Blank finals 对于根据条件以不同方式初始化某些东西也很有用:

final Client myClient;
if (someCondition) {
    myClient = foo();
}
else {
    myClient = bar();
}
// do stuff with myClient
于 2012-06-19T01:41:34.103 回答
1

将代码放入构造函数中:

final Client myClient;

public MyClass() throws SomeException {
    myClient = library.getClient("service");
}
于 2012-06-19T01:11:52.957 回答
0

当然,至少有两个微不足道的选择:

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

两者都有优点和缺点。

于 2012-06-19T01:09:22.527 回答
0

您可以将代码的不同部分拆分为方法并将 myClient 作为最终变量移交...您还可以将所有代码添加到一个 try 块中并抛出和处理不同的异常。这是可能的,如果您不需要异常部分中的 var ......全局变量也可能是一个解决方案,但不是一个好的解决方案......有一个地面角色。如果您看不懂代码,请将其拆分为方法和类

于 2012-06-19T01:14:54.167 回答
0

作为包装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;
}
于 2012-06-19T01:15:55.593 回答