因此,我偶然发现了一段Java代码,并注意到如果用户被禁止,则登录功能返回3(int)。结果集和用于登录的准备好的语句的关闭是在返回之后进行的,因此,如果禁止了该用户,则它实际上永远不会关闭。 我的问题是,如果函数返回3,它会到达“最终”部分并关闭所有内容吗?
我创建了一个布尔值,如果播放器被禁止,则布尔值设置为true。然后,在函数返回“ loginok”的末尾,我添加了:
if(Banned)
return 3;
else
return loginok;
这应该可行,但是我想知道以前的方法是否正确。
代码看起来像这样:
public int login(String login, String pwd) {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = con.prepareStatement("SELECT id, password, banned WHERE name = ?");
ps.setString(1, login);
rs = ps.executeQuery();
if (rs.next()) {
int banned = rs.getInt("banned");
if (rs.getByte("banned") == 1) {
return 3;
}
accId = rs.getInt("id");
String passhash = rs.getString("password");
ps.close();
rs.close();
if (getLoginState() > LOGIN_NOTLOGGEDIN) {
loggedIn = false;
loginok = 7;
} else if (pwd.equals(passhash)) {
loginok = 0;
} else {
loggedIn = false;
loginok = 4;
}
}
} catch (SQLException e) {
log.error("ERROR", e);
} finally { //Or maybe its fine because of this?
try {
if (ps != null && !ps.isClosed()) {
ps.close();
}
if (rs != null && !rs.isClosed()) {
rs.close();
}
} catch (SQLException e) {
}
}
return loginok;
}
答案 0 :(得分:2)
以前的方法还可以。 return
子句将被执行。
在这种情况下:执行finally
语句,运行{{1}}块,该方法实际上返回。
答案 1 :(得分:1)
强烈建议您重构该代码以使用try-with-resources。
public int login(String login, String pwd) {
Connection con = DatabaseConnection.getConnection();
try (PreparedStatement ps = con.prepareStatement("SELECT id, password, banned WHERE name = ?")) {
ps.setString(1, login);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
if (rs.getByte("banned") == 1) {
return 3;
}
accId = rs.getInt("id");
String passhash = rs.getString("password");
if (getLoginState() > LOGIN_NOTLOGGEDIN) {
loggedIn = false;
loginok = 7;
} else if (pwd.equals(passhash)) {
loginok = 0;
} else {
loggedIn = false;
loginok = 4;
}
}
}
} catch (SQLException e) {
log.error("ERROR", e);
}
return loginok;
}
现在的问题是有争议的,因为它们将始终封闭。
答案 2 :(得分:0)
您应该将ARM与Java 7一起使用。这样,您不必担心在finally块中关闭资源,但是您确实需要捕获异常。但是,您的代码中有一个小缺陷。您不应该使用if块来遍历结果集。您只会选择结果集的第一行,而不会遍历其余部分。
您的代码可以是这样的
try(Connection con = DatabaseConnection.getConnection();
ps = con.prepareStatement("SELECT id, password, banned WHERE name = ?");) {
ps.setString(1, login);
try(ResultSet rs = ps.executeQuery();) {
while (rs.next()) {
... You calculations here ...
}
}
}
您不需要关闭任何资源。
答案 3 :(得分:0)
对您的问题:
如果函数返回3,它会到达“最终”部分并关闭所有内容吗?
是的,它总是到达finally
块。这就是finally块的用途。
此外,您应该记住始终释放要分配的资源。正如其他答案所指出的那样,由于Java 7可以使用“尝试资源”,因此,由于finally块是隐式的,因此更易于使用。
在长时间不间断运行的应用程序(例如Web应用程序)中,关闭资源特别重要。否则,您将开始非常快地失去资源,并且服务器将需要非常频繁地重新启动。