Правильно ли я использую 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 76

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 все равно закрывается. Вы можете найти более подробную информацию здесь и здесь.