Правильно ли я использую Java 7 try-with-resources
Я ожидаю, что буферизованный читатель и читатель файлов закроются, а ресурсы будут освобождены, если исключение будет выброшено.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
однако, есть ли требование иметь catch
условие для успешного закрытия?
EDIT:
по существу, приведенный выше код в Java 7 эквивалентен ниже для Java 6:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(filePath));
return read(br);
}
catch (Exception ex)
{
throw ex;
}
finally
{
try
{
if (br != null) br.close();
}
catch(Exception ex)
{
}
}
return null;
}
2 ответа:
это правильно, и нет никаких требований к
catch
предложения. Oracle java 7 doc говорит, что ресурс будет закрыт независимо от о том, действительно ли выбрасывается исключение или нет.вы должны использовать
catch
предложение только если вы хотите реагировать на исключение. Элементcatch
предложение будет выполнено после ресурс закрыт.вот фрагмент из учебник Oracle:
в следующий пример считывает первую строку из файла. Он использует экземпляр BufferedReader для чтения данных из файла. Командой bufferedreader это ресурс, который должен быть закрыт после завершения программы с это:
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } // In this example, the resource declared in the try-with-resources statement is a BufferedReader.
... Поскольку экземпляр BufferedReader объявлен в a оператор try-with-resource, он будет закрыт независимо от того, будет ли оператор try завершается нормально или резко (в результате метод BufferedReader.с readline бросая IOException).
EDIT
относительно нового отредактированного вопроса:
код в Java 6 выполняет
catch
а потомfinally
блок. Это приводит к тому, что ресурсы все еще потенциально открыты вcatch
блок.в синтаксисе Java 7 ресурсы закрыты до the
catch
блок, поэтому ресурсы уже закрыты во времяcatch
исполнения блока. Это задокументировано в ссылка выше:в операторе try-with-resources выполняется любой catch или finally block после того, как объявленные ресурсы были закрыты.
ваше использование try-with-resources будет работать нормально в этом конкретном случае, но это не совсем правильно в целом. Вы не должны цеплять такие ресурсы, потому что это может привести к неприятным сюрпризам. Предположим, у вас есть переменный размер буфера:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz)) { return read(br); } }
предположим что-то пошло не так, и вы закончили с
sz
отрицательное. В этом случае ваш файловый ресурс (созданный черезnew FileReader(filePath)
) составит не быть закрыты.чтобы избежать этой проблемы, вы должны укажите каждый ресурс отдельно следующим образом:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (FileReader file = new FileReader(filePath); BufferedReader br = new BufferedReader(file, sz)) { return read(br); } }
в этом случае даже если инициализации
br
неfile
все равно закрывается. Вы можете найти более подробную информацию здесь и здесь.