java:如何声明最终一个在 try - catch 块内初始化的变量?

发布于 2025-01-07 14:29:07 字数 1309 浏览 5 评论 0原文

我有一个变量在初始化后不应更改其值,因此我想将其定义为最终变量。

问题是变量必须在 try 块内初始化,所以我遇到了以下麻烦:

我有以下代码:

Connection conn = null;
try {
    conn = getConn(prefix);
    [...do some stuff with conn...]
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}

如果我将变量声明为final,而不将其初始化为 null,我会得到一个“局部变量 conn”可能尚未在finally 块上初始化。另一方面,如果我将其声明为 Final 并将其初始化为 null,则会在 try 块中收到错误“无法分配最终局部变量 conn”。

编辑:在 lxx 回答之后,我使用了这个版本

try {
    final Connection conn = conn = getConn(prefix);
    try {
        return selectAll(conn, sql, params);
    } catch (Exception e) {
        throw new DbHelperException("error executing query", e);
    } finally {
        closeConnection(conn);  
    }
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
}

所以这应该是这样做的方法?

--

经验教训:

我认为问题的正确答案是 lxx 给出的答案,但在这种情况下,我猜声明变量 Final 的缺点超过了它的好处...

--

编辑:在堆栈上发现了两个问题关于何时使用 Final 的溢出

什么时候应该对方法参数和局部变量使用 Final?

<一href="https://stackoverflow.com/questions/137868/using-final-modifier-whenever-applicable-in-java">在java中适用时使用“final”修饰符

I have a variable that is not supposed to change its value after it's been initialized, so I want to define it as a final variable.

the problem is that the variable has to be initialized inside a try block, so I get the following troubles:

I have the following code:

Connection conn = null;
try {
    conn = getConn(prefix);
    [...do some stuff with conn...]
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}

If I declare the variabale as final, without initializing it to null, I get a 'The local variable conn may not have been initialized' on the finally block. On the other hand, if I declare it final and initialize it to null, I get the error 'The final local variable conn cannot be assigned' in the try block.

EDIT: after lxx answer, I came with this version

try {
    final Connection conn = conn = getConn(prefix);
    try {
        return selectAll(conn, sql, params);
    } catch (Exception e) {
        throw new DbHelperException("error executing query", e);
    } finally {
        closeConnection(conn);  
    }
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
}

So this should be the way to do it?

--

Lesson learned:

I think that the correct answer to the question is the one that lxx gave, but in this case I guess that the cons of declaring the variable final outweights it's benefits...

--

EDIT: found two questions on stack overflow about when to use final

When should one use final for method parameters and local variables?

Using "final" modifier whenever applicable in java

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

入画浅相思 2025-01-14 14:29:07

您可以更准确地处理异常。如果您在打开连接时遇到异常,我想您不必在finally块中关闭它。如果之后在 try 块中遇到异常,并在新的嵌套 try-catch 块中处理异常,则无需在外部定义变量。像这样的东西:

    try {
        final Connection conn = getConn(prefix);
        try {
            //code using conn
        } catch (Exception e) {

        } finally {
            closeConnection(conn);
        }
    } catch (DbHelperException e) {
        throw new DbHelperException("error opening connection", e);
    }

You could handle the Exceptions more accurately. If you get an Exception opening the connection, you don't have to close it in the finally block I guess. If you get an exception after that, in the try block, and handle the exception in a new nested try-catch block you don't need to define the variable outside. Something like:

    try {
        final Connection conn = getConn(prefix);
        try {
            //code using conn
        } catch (Exception e) {

        } finally {
            closeConnection(conn);
        }
    } catch (DbHelperException e) {
        throw new DbHelperException("error opening connection", e);
    }
谈下烟灰 2025-01-14 14:29:07

这个怎么样?

Connection temp = null;
try {
    temp = getConn(prefix);
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}
final Connection conn = temp;

How about this?

Connection temp = null;
try {
    temp = getConn(prefix);
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}
final Connection conn = temp;
尘世孤行 2025-01-14 14:29:07

为什么你想要最终的结果?如果您想将其传递给匿名内部类,您可以这样做:

Connection conn = null;
try {
    conn = getConn(prefix);
    final Connection finalConn = conn;
    // pass it to inner class here
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}

此解决方案的唯一问题(也是一个很大的问题)是,一旦离开此块,您就会关闭连接。因此,除非您立即声明并调用您的匿名内部类,否则这种模式将不起作用。

不管怎样,如果我是你,我可能会重新表述整个事情,将前缀设为final,并将连接处理委托给匿名内部类。

Why do you want it final? If you want to pass it to an anonymous inner class, you could do:

Connection conn = null;
try {
    conn = getConn(prefix);
    final Connection finalConn = conn;
    // pass it to inner class here
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}

The only problem (and quite a big one) with this solution is that you close your connection as soon as you leave this block. So unless you declare and call your anon inner class straight away, this pattern isn't going to work.

Either way, I'd probably rephrase the whole thing if I were you, making prefix final instead and delegating connection handling to the anon inner class.

纵情客 2025-01-14 14:29:07

您可以尝试在 catch 和 finally 块中分配它吗?
就像这样:

Connection connTemp = null;
final Connection conn;
try {
    connTemp = getConn(prefix);
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}
conn = connTemp;

Can you try assigning it in both the catch and finally blocks?
Like so:

Connection connTemp = null;
final Connection conn;
try {
    connTemp = getConn(prefix);
} catch (Exception e) {
    throw new DbHelperException("error opening connection", e);
} finally {
    closeConnection(conn);
}
conn = connTemp;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文