Java: указание обобщений на тип и реализацию - PullRequest
1 голос
/ 27 января 2009

Большинство ссылок, которые я видел, и завершение кода в моей среде IDE содержат определение общего типа как для типа переменных, так и для его реализации, например.

List<String> string = new ArrayList<String>();

Недавно я начал пропускать универсальный тип в реализации, например.

List<String> strings = new ArrayList();

при условии, что компилятор проверяет только тип на его неповторимость generics voodoo, и что реализация не должна заботиться об этом, поскольку его универсальные типы стираются при компиляции и не влияют на время выполнения вообще.

Я наивный? Есть ли причина для включения универсального типа в реализацию?

Ответы [ 4 ]

6 голосов
/ 27 января 2009

Компилятор может позволить вам писать код с такими назначениями (в зависимости от ваших настроек предупреждений / ошибок), но это небезопасно. Вот пример:

List<Date> dates = new ArrayList<Date>();
List list = dates;
List<String> strings = list;

strings.add("a");
Date d = dates.get(0); // Boom!!
4 голосов
/ 27 января 2009

Есть ли причина для включения универсального типа в реализацию?

Требуется, поскольку не обязательно будет таким же:

List<? extends Number> numbers = new ArrayList<Integer>();

Один из способов избежать этого в обычных случаях - это использовать статические служебные методы, а остальное делает вывод типа компилятора:

class CollectionUtilities {
   static <T> ArrayList<T> arrayList () { return new ArrayList<T>(); }
}

...

import static CollectionUtilities.*;

List<Integer> numbers = arrayList();

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

0 голосов
/ 27 января 2009

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

Однако, только в немного более сложном случае вы можете столкнуться с неприятностями. Вот почему компилятор хочет выдать предупреждение для этого типа кода. Кроме того, если добавлено преобразование типов (Java 8?), Этот код будет нарушен. Если только Java 7 не добавит вывод типа первым. : -)

Между тем, вероятно, лучше всего написать предупреждающий чистый код.

0 голосов
/ 27 января 2009

Хотя было бы неплохо иметь возможность пропустить определение общего типа в этих случаях, оно выдает предупреждения. (Существует серьезное предложение расширить язык с помощью необработанного синтаксиса для определения типа здесь.) Вы действительно не должны привыкать игнорировать предупреждения компилятора. В качестве Пита Киркхэма вы можете использовать уже выведенный тип (хотя я предлагаю использовать более короткие имена).

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