Предупреждение о утечке ресурсов в eclipse
В Eclipse
я получил предупреждение Resource leak: 'ps' is not closed at this location
, которое я не понимаю.
В моем коде Java
я объявляю "ps" как подготовленное выражение, и я использую (и закрываю) его много раз. Тогда у меня есть следующая последовательность:
try {
if(condition) {
ps = c.prepareStatement("UPDATE 1 ...");
} else {
ps = c.prepareStatement("UPDATE 2 ...");
}
ps.executeUpdate();
} catch (SQLException e) {
// exception handling
} finally {
if (null != ps)
try {
ps.close();
} catch (SQLException e) {
// exception handling
};
}
"Утечка ресурсов". Предупреждение начинается с "Обновить" в разделе "Другие".
Если я установил ps = null
, прежде чем запустить блок try, предупреждение не будет.
Если второй оператор UPDATE-Statement закомментирован, предупреждение не будет отображаться.
Является ли это проблемой понимания или java/eclipse?
Ответы
Ответ 1
Если у вас есть это предупреждение, вы используете Java 7. В этом случае вы не должны закрывать ресурс, который реализует AutoClosable
самостоятельно. Вы должны инициализировать эти ресурсы в специальной секции инициализации try
statementcommented:
// decide which update statement you need:
// (your if should be here)
String update = ....;
try (
ps = c.prepareStatement(update);
) {
// use prepared statement here.
} catch (SQLException) {
// log your exception
throw new RuntimeException(e);
}
// no finally block is needed. The resource will be closed automatically.
Я действительно не знаю, почему присутствие оператора if/else
приводит к появлению или исчезновению предупреждения. Но java 7 рекомендует работать с автоматически закрываемыми ресурсами, которые я описал выше, поэтому попробуйте это.
Ответ 2
Я думаю, это проблема с проверкой, которую вы используете.
Разделите свой код на блоки initialization
и use
. Кроме того, исключить исключение из блока инициализации (или выполнить раннее возвращение). Таким образом, нет необходимости проверять значение null при отпускании ресурса после use
block
// initialization
// Note that ps is declared final.
// I think it will help to silence your checker
final PreparedStatement ps;
try {
if( bedingungen ... ) {
ps = c.prepareStatement("UPDATE 1 ...");
} else {
ps = c.prepareStatement("UPDATE 2 ...");
}
}
catch (SQLException e) {
log.error("Problem creating prepared statement, e );
throw e;
}
// use
try {
ps.executeUpdate();
} catch (SQLException e) {
log.error("Problem decrementing palets on " + srcElement.getName() +
": " + e.getMessage());
}
finally {
try {
ps.close();
} catch (SQLException e) {
log.warn("Error closing PreparedStatement: " + e.getMessage());
};
}
Ответ 3
Измените имя переменной с c на mC. Я думаю, что это странный сбой при использовании c в качестве имени переменной. Спасибо Чарли