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

Почему AutoCloseable базовый интерфейс для Closeable (а не наоборот)?

Насколько я знаю, интерфейс Closeable был связан с Java 1.5 и AutoCloseable был введен в Java 1.7.
Я пытаюсь понять, почему Closeable extends AutoCloseable, а не наоборот? Это делается из-за обратной зависимости (неспособности изменить интерфейс Closeable), т.е. Необходимость в AutoCloseable иметь более широкое исключение, чем Closeable? Или моя логика ошибается, и так должно быть?

4b9b3361

Ответ 1

Таким образом, весь код пользователя, который реализовал Closeable, автоматически получает возможность реализовать AutoCloseable, что позволяет им автоматически извлекать выгоду из синтаксиса try-with-resources.

Ответ 2

Комментарий @Sotirios Delimanolis прибил его.

Команда Java 7 хотела, чтобы механизм маркирования объектов был автоматически закрыт для конструкции "попробуйте с ресурсами". К сожалению, спецификация API для метода Closeable.close() слишком строгая. Это требует, чтобы метод close() был идемпотентом... но это не обязательно в случае использования "попробуйте с ресурсами".

Таким образом, они ввели интерфейс AutoClosable с менее ограничительным семантиком close()... и ретро-установленным Closeable в качестве подтипа AutoCloseable.

Другое дело, что AutoCloseable.close() объявляется как throw Exception, а не IOException. Это означает, что API AutoCloseable менее ограничительный, чем Closeable... и учитывая, что он эффективно используется в качестве API обратного вызова в try-with-resources, это делает его более гибким/более широко применимым. (API можно использовать для ресурсов, которые не имеют ничего общего с I/O, но все же могут генерировать исключения при закрытии.) Флип-бок - это то, что Java-типизация не позволит им сделать такое изменение, если метод closes() throws Exception были введены в подтип.


Альтернативы были бы следующими:

  • чтобы ограничить "попробовать с ресурсами" ресурсам с помощью идемпотентного закрытия... что ограничивает его полезность или

  • чтобы ретроспективно изменить семантику Closeable.close()..., что может привести к трудностям для переноса старого кода на Java 7

  • чтобы ретроспективно изменить подпись Closeable.close()..., которая нарушила бы двоичную совместимость.

Ответ 3

Интерфейс Closeable был введен в Java 5. Когда в Java 7 был введен try-with-resources (ниже примерный код), разработчики языка хотели изменить некоторые вещи, но нуждались в обратной совместимости (весь код, написанный в предыдущих версиях, не должен устаревать с введением новых функциональных возможностей) поэтому они создали Superinterface AutoCloseable с правилами, которые они хотели.

Пример попытки с ресурсами:

    try (NewResource a = NewResource.CreateResource();
{
    }

Над кодом "Попробуйте с ресурсами". Мы просто можем понять, что в этом коде мы можем объявить новую переменную в коде try, и эта переменная может вызвать другие методы в коде. Помимо уменьшения детализации блока try этот код также не требует блока finally, но исполняющая среда должна быть Java 7 или выше. Хотя, наконец, создается самой JVM.

Интерфейс

Closeable и AutoCloseable содержит только один метод

void close()

В то время как close () метод Closeable throws IOException, AutoCloseable close() метод выбрасывает Exception.

Ответ 4

Closeable имеет некоторые ограничения, поскольку он может только бросать IOException, поэтому его нельзя изменить без нарушения устаревшего кода. Итак, был введен AutoCloseable, который может бросать Exception.

AutoCloseable должен использоваться для приложений с помощью > JDK7.

Поскольку библиотеки JDK7 + используют AutoCloseable, а устаревший код, который реализует Closeable, по-прежнему должен быть совместим с JDK7 + это делается для того, чтобы Closeable расширял AutoCloseable.

public interface Closeable extends AutoCloseable {
    public void close() throws IOException;
}

AutoCloseable был специально разработан для работы с операторами try-with-resources. Поскольку Closeable extends AutoCloseable, try-with-resources могут использоваться для закрытия любых ресурсов, которые реализуют либо Closeable, либо AutoCloseable.