Зачем нужен класс FilterInputStream?

252
07 ноября 2017, 23:52

Просмотрев документацию и исходный код класса FilterInputStream, а также код его наследников, возник вопрос: зачем вообще нужен этот класс?

Т.к. этот класс не является источником данных, не выполняет никакой полезной работы, то вероятно единственная цель его существования - решение каких-то архитектурных проблем.

Как я сейчас понимаю - система ввода/вывода java.io использует паттерн декоратор. Если классам наследникам FilterInputStream необходимо делегировать часть поведения потоку ввода, ссылку на который они принимают у себя в конструкторе, они не обращаются к методам FilterInputStream, а вызывают эти методы сразу по этой ссылке. Единственная вещь в FilterInputStream, которая используется всеми его наследниками, это ссылочное поле protected volatile InputStream in. Но ведь это всего лишь одно единственное поле и совершенно не сложно объявить его в самих наследниках FilterInputStream.

Пожалуйста, скажите прав я или нет, и если нет — то в чем я ошибаюсь или что я не учел.

Answer 1

Единственная вещь в FilterInputStream, которая используется всеми его наследниками, это ссылочное поле protected volatile InputStream in.

По порядку, все что делает FilterInputStream:

  • содержит поле in, которое наследники могут использовать;
  • объявляет конструктор, который принимает InputStream — каждому наследнику придется объявить хотя бы один конструктор и вызвать конструктор FilterInputStream;
  • создает реализации по-умолчанию для всех методов InputStream, делегируя их вложенному потоку — девять методов, которые наследники могут не переопределять.

Т.е. если бы не было FilterInputStream каждому из его наследников пришлось бы:

  • объявить поле для вложенного потока;
  • принимать в конструкторе поток и инициализировать поле;
  • создать шаблонные реализации для всех методов InputStream вида:

    public int read() {
         return in.read();
    }
    

За счет наличия шаблонных реализаций наследник может переопределить только те методы, поведение которых специфично для наследника. Например, CheckedInputStream переопределяет три метода FilterInputStream, а наследует шесть.

В документации указано 11 наследников FilterInputStream (это только в стандартной библиотеке). Дублировать поле и инициализацию уже было бы плохо. Вставлять же в каждый из классов одинаковые делегирующие методы недопустимо.

Answer 2

FilterInputStream - это декоратор для InputStream. Декораторов на InputStream существует целое множество: к примеру, BufferedInputStream и ZipOutputStream.

Он реализует все те же методы, что и InputStream, который лежит в нём, но позволяет к ним добавить доп. функционал. Конкретно его используют для какой-либо модификации данных из InputStream (т.е. фильтрации).

Для лучшего понимания почитайте про паттерн декоратор

READ ALSO
Как убрать анимацию вращения у Progress bar?

Как убрать анимацию вращения у Progress bar?

Доброго времени суток, необходимо на круглом progress bar отображать рейтинг заведенияТ

275
Получить сообщения Facebook Graph Api

Получить сообщения Facebook Graph Api

Пытаюсь получить сообщения с Graph Api, делаю запрос:

248
Команда java не работает

Команда java не работает

В консоли не работает ни java, ни javacИз-за этого установщик (start

266
C# Автозапуск приложения из реестра

C# Автозапуск приложения из реестра

Записываю в реестр значение:

362