V6128. Using a Closeable object after it was closed can lead to an exception.
Анализатор обнаружил вызов метода объекта, у которого ранее был вызван метод close. Подобные действия могут привести к выбрасыванию исключения.
Рассмотрим пример:
public void appendFileInformation(String path) throws IOException {
FileInputStream is = new FileInputStream(path);
// ....
is.close();
// ....
if (is.available() == 0) {
System.out.println("EOF");
}
// ....
}
В условии проверяется, что файл был прочитан полностью. Для проверки сравнивают количество оставшихся байтов с нулём. Проблема в том, что при вызове метода available будет выброшено исключение типа IOException с сообщением Stream Closed. Это связано с тем, что перед условием у переменной is вызывается метод close. Следовательно, ресурсы is будут освобождены.
Рассмотрим корректную реализацию appendFileInformation:
public void appendFileInformation(String path) throws IOException {
try (FileInputStream is = new FileInputStream("out.txt")) {
// ....
if (is.available() == 0) {
System.out.println("EOF");
}
// ....
}
}
Для корректной работы метода стоит использовать try-with-resources. В этом случае:
- ресурсы объекта
isбудут автоматически освобождены после выхода из телаtry; - вне тела
tryобратиться к объекту не получится — это даёт дополнительную защиту от исключений типаIOException; - даже если в теле
tryвозникнет исключение, ресурсы всё равно будут освобождены.
Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки управления динамической памятью (выделения, освобождения, использования освобожденной памяти) [* см. примечание касательно языков C#, Java]. |
Данная диагностика классифицируется как: