我有一个变量,它不应该在初始化后改变它的值,所以我想把它定义为最终变量。
问题是变量必须在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,则会在finally块上得到“局部变量conn可能尚未初始化”。另一方面,如果我将其声明为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给出的答案,但在这种情况下,我认为宣布变量最终的利弊超出了它的好处......
-
编辑:发现有关何时使用最终
的堆栈溢出的两个问题When should one use final for method parameters and local variables?
答案 0 :(得分:7)
您可以更准确地处理例外情况。如果你得到一个异常打开连接,你不必在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);
}
答案 1 :(得分:2)
这个怎么样?
Connection temp = null;
try {
temp = getConn(prefix);
} catch (Exception e) {
throw new DbHelperException("error opening connection", e);
} finally {
closeConnection(conn);
}
final Connection conn = temp;
答案 2 :(得分:-1)
为什么你想要它最终?如果你想将它传递给一个匿名的内部类,你可以这样做:
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);
}
使用此解决方案的唯一问题(也是相当大的问题)是您在离开此块时立即关闭连接。因此,除非你立即宣布并召唤你的内部班级,否则这种模式将无法发挥作用。
无论哪种方式,如果我是你,我可能会改写整个事情,将prefix
改为最终,并将连接处理委托给anon内部类。
答案 3 :(得分:-2)
你能尝试在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;