Подтвердить что ты не робот

Я правильно использую 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;
}
4b9b3361

Ответ 1

Правильно, и нет требования к предложению 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 объявлен в try-with-resource, он будет закрыт независимо от того, будет ли оператор try завершается нормально или внезапно (в результате метод BufferedReader.readLine, генерирующий исключение IOException).

ИЗМЕНИТЬ

Относительно нового отредактированного вопроса:

Код в Java 6 выполняет catch, а затем блок finally. Это заставляет ресурсы по-прежнему потенциально открываться в блоке catch.

В синтаксисе Java 7 ресурсы закрываются перед блоком catch, поэтому ресурсы уже закрыты во время выполнения блока catch. Это описано в приведенной выше ссылке:

В операторе try-with-resources выполняется любой блок catch или finally после того, как объявленные ресурсы были закрыты.

Ответ 2

В этом конкретном случае ваше использование 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)) будет закрыт NOT.

Чтобы избежать этой проблемы, вы должны указать каждый ресурс отдельно следующим образом:

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