2013-07-08 1 views
14

Это может быть глупо, но я хочу знать разницу в работе фона.Какая разница в использовании InputStream вместо FileInputStream при создании объекта FileInputStream

  1. InputStream is = new FileInputStream(filepath);
  2. FileInputStream is = new FileInputStream(filepath);

В чем разница между этими двумя строками кода и в каких сценариях они используются.

+0

FileInputStream получен из InputStream - любой экземпляр FileInputStream обязательно является InputStream. Широкое предпочтение делает объявления максимально абстрактными. – user888379

+0

Нет разницы, поскольку вы оба делаете оба в обоих случаях. – EJP

+1

Возможный дубликат [Java - объявление из типа интерфейса вместо класса] (http://stackoverflow.com/questions/3383726/java-declaring-from-interface-type-instead-of-class) – Tom

ответ

19

FileInputStream extends InputStream: это специализированная версия InputStream, предназначенная для чтения файлов.

Существует несколько вариантов использования InputStream в соответствии с его использованием.

Обычно рекомендуется использовать самый высокий тип, необходимый для вашего кода. Поэтому, если вашему коду необходимо прочитать данные с InputStream, но не конкретно от FileInputStream, вы должны использовать InputStream. Однако, если вам нужно сохранить информацию о вашем объекте как FileInputStream, а не только InputStream, тогда вы должны сохранить тип FileInputStream.

12

Нет никакой реальной разницы. FileInputStream расширяет InputStream, поэтому вы можете назначить объект InputStream объектом FileInputStream. В конце концов, это тот же объект, поэтому будут выполняться те же операции.

Это поведение называется Polymorphism и очень важно в объектно-ориентированном программировании.

Ваша первая строка кода, вероятно, более желательна, чем вторая, поскольку она не блокирует вас в FileInputStream.

Это одна из сильных сторон объектно-ориентированного программирования. Не указывая тип, вы можете изменить тип потока, который вы используете позже. Если вы уверены, что вам понадобится только FileInputStream, используйте вторую строку кода.

2

Нет никакой разницы. В каждом случае вы создаете FileInputStream. Первый, вероятно, лучший стиль программирования, в котором вы обычно должны использовать классы interface вместо конкретного класса, чтобы обеспечить гибкость (т. Е. Вы решили использовать BufferedInputStream).

4

Как и в другом состоянии ответа, нет никакой разницы в поведении. Это все тот же объект, и будут выполнены одни и те же методы. Вы можете назначить объект любого типа, который наследует эту переменную InputStream.

Тем не менее, о чем никто не упоминал до сих пор: вы можете только вызывать операции, объявленные в InputStream по этой переменной. Если FileInputStream предложит некоторые дополнительные операции, компилятор вызовет ошибку, если вы попытаетесь вызвать его. В этом случае вам нужно будет использовать FileInputStream как тип переменной.

3

Другие ответы довольно много прибивали его, но я хотел бы добавить следующий бит.

Если тип ссылочной переменной is является строго внутренней конструкцией вашего класса, т.е.ни один другой класс никогда не узнает об этом, прямо или косвенно, тогда нет никакой разницы между этими двумя утверждениями, хотя я бы запрограммировал более базовый тип (InputStream) только потому, что.

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

Конечно, это общепринятая практика и относится к большему, чем InputStreams и тому подобное.

+0

Хорошее дополнение, хорошая работа. –