Почему люди создают arraylist таким образом?

#java

#java

Вопрос:

Иногда я вижу, как кто-то создает arraylist подобным образом, почему?

 List numbers = new ArrayList(  );
  

Вместо:

 ArrayList<something> numbers = new ArrayList<something>();
  

Комментарии:

1. Раньше не было дженериков (в JDK 65 и выше были представлены дженерики), поэтому использовалась версия 1 вашего примера кода (просто боковое примечание ).

Ответ №1:

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

Если вопрос был о неиспользовании дженериков, то это плохо. Дженерики всегда хороши, поскольку они обеспечивают безопасность типов.

Ответ №2:

Что хорошо: 1. Список — это общий случай для многих реализаций.

 List trololo = new ListImpl();
  
  1. Скрывает реальную реализацию для пользователя:

    общедоступный список giveMeTheList(){ List trololo = new SomeCoolListImpl(); возвращает trololo; }

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

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

 List<?> trololo = new ListImpl<?>();
  

В общем, подстановочный знак имеет то же значение: вы не знаете наверняка, будет ли ваша коллекция разнородной или однородной?

Ответ №3:

Когда-нибудь вы могли бы сделать: List<something> numbers = new LinkedList<something>(); без изменения клиентского кода, который вызывает numbers .

Ответ №4:

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

  • Вы полностью уверены, что выбранная реализация удовлетворит ваши потребности.
  • Вам нужна некоторая специфичная для реализации функция, которая недоступна через интерфейс, например ArrayList.trimToSize()

Конечно, вы можете использовать приведение, но тогда использование интерфейса вообще не имеет смысла.

Ответ №5:

Первая строка — это Java в старом стиле, нам приходилось делать это до того, как в Java 1.5 появились дженерики. Но многие блестящие разработчики программного обеспечения по-прежнему вынуждены использовать Java 1.4 (или меньше), потому что их компании боятся риска и усилий по обновлению приложений…

Хорошо, это было неофициально. Много устаревшего кода было создано на Java 1.4 или менее и не подвергалось рефакторингу.

Вторая строка включает в себя обобщения (так что это явно 1.5 ), а переменная объявлена как ArrayList . На самом деле большой проблемы нет. Конечно, всегда лучше кодировать для интерфейсов, поэтому, по моему (и другим) мнению, не объявляйте переменную как, ArrayList если вам действительно не нужны специальные ArrayList методы.

Ответ №6:

В большинстве случаев, когда вас не волнует реализация, лучше программировать для интерфейса. Итак, что-то вроде:

 List<something> numbers = new ArrayList<something>();
  

было бы предпочтительнее, чем:

 ArrayList<something> numbers = new ArrayList<something>();
  

Причина в том, что вы можете настроить свою программу позже по соображениям производительности.

Но вы должны быть осторожны, чтобы просто не выбрать наиболее общий доступный интерфейс. Например, если вы хотите иметь отсортированное множество вместо Set, вы должны запрограммировать на SortedSet , вот так:

 SortedSet<something> s = new TreeSet<something>();
  

Если вы просто нагло используете интерфейс, подобный этому:

 Set<something> s = new TreeSet<something>();
  

Кто-то может изменить реализацию на HashSet, и ваша программа будет сломана.

Наконец, эта программа для интерфейса будет даже намного полезнее, когда вы определите общедоступный API.

Ответ №7:

Два отличия заключаются в том, что numbers в первой строке используется тип List , а не ArrayList . Это возможно, потому что ArrayList является потомком List ; то есть в нем есть все, что List есть, поэтому он может заполнять List объект. (Это не работает наоборот.)

Набрана вторая строка ArrayList . Это означает, что второй numbers список может содержать только объекты типа something .