Способ создания общей коллекции с помощью оператора Java5 + diamond - PullRequest
3 голосов
/ 04 ноября 2011

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

Таким образом можно объявить:

private Set set = new HashSet<String>();

И затем, в этой строке hashset, добавить собак или что-нибудь к этому набору, без каких-либо проблем, поскольку нет никаких проверок во время выполнения, как для массивов (ArrayStoreException ...) (но у вас могут быть проблемы, такие как classcast, когда вы используете этот набор ...

Итак, я хочу сказать, что мы обычно создаем экземпляры родовых коллекций таким образом:

Set<String> set = new HashSet<String>();

У меня вопрос: почему мы ставим тип HashSet, так как действительно важен только тип ссылки на переменную (я думаю).

Я имею в виду, мы могли бы просто написать:

Set<String> set = new HashSet();

И это будет работать точно так же, верно? Итак, почему мы обычно пишем тип во время создания экземпляра? (это не обязательно)


Редактировать

Я знаю о "операторе алмаза" для вывода типа, но зачем нам это вообще нужно !!! так как вывод типа уже работает!

следующий код:

            Set<String> set = new HashSet();
            set.add("Test add a string 1");
            set.add("Test add a string 2");
            for ( String s : set ) {
                    System.out.println(s);
            }

Производит вывод:

Тест добавить строку 1 Тест добавить строку 2

Проверь это сам http://ideone.com/vuiCE

Итак, теперь вы говорите о выводе типов как функции Java7, но он уже работает для меня ...

с java7 мне придется заменить мой

            Set<String> set = new HashSet();

К

            Set<String> set = new HashSet<>();

Это все еще 2 дополнительных символа для того же, нет? (Если дженерики не только время компиляции с Java7? Я не знаю)

Ответы [ 5 ]

4 голосов
/ 04 ноября 2011

И это будет работать точно так же, верно?

Во время выполнения: Да .

Во время компиляции: Нет

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

Когда вы пишете new HashSet(), вы используете raw type .Я имею в виду этот вопрос относительно его значения и причин, по которым его следует избегать:


В общем, вы можете поспорить так:

Set<String> set = new HashSet();

недалеко от

HashSet tmp = new HashSet();
...
Set<String> set = tmp;

, что, в свою очередь, недалеко от

HashSet tmp = new HashSet();
tmp.add(7);
...
Set<String> set = tmp;

Который все еще компилируется, но плохо по тысяче причин:)


Java 7 позволяет вам писать

Set<String> set = new HashSet<>();

, что говорит компилятору вывод тип между < ... >.

Документация по «Оператору алмазов»:

3 голосов
/ 04 ноября 2011

Ваше предложение в конце является выводом типа и было введено в Java 7 через так называемый оператор diamond:

Set<String> set = new HashSet<>();

Так что да, это могло быть только с самого начала. Но это Java, и обычно требуется несколько десятилетий, чтобы одобрить новую языковую функцию (<- небольшое преувеличение) </p>

1 голос
/ 05 ноября 2011

Хотя в настоящее время Java стирает информацию общего типа, они очень тщательно проектировали язык и библиотеки, чтобы в будущем можно было добавить обратно полную информацию общего типа (так называемое повторение).Любой правильно написанный общий код (то есть без предупреждения javac) выживет при таком изменении языка.В вашем примере, версия с бриллиантами - это будущее;исходной версии нет - она, конечно, все равно должна компилироваться, но она вызовет исключение приведения типа во время выполнения.

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

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

JDK - самый виновный.API JDK тщательно разработаны, чтобы пережить реификацию;однако реализации зависят от стирания.Если Java добавляет reification, эти коды JDK должны быть переписаны.Команда Java будет крайне лицемерна, если они обвинят нас в написании неверного кода, в то время как они сами должны сделать то же самое.

Учитывая количество кода, которое не может пережить реализацию без переписывания, мы можем безопасноСкажем, Java никогда не добавит реификацию, если она сохраняет приверженность обратной совместимости.

В таком случае, да, как угодно.Ничего страшного в Set<String> set = new HashSet().Лично я всегда добавляю <>, чтобы избежать предупреждения.(На самом деле, когда это возможно, я постараюсь сделать мой код защищенным от повторного кода, что, как я уже сказал, является бредовым поступком)

В вашем примере логический вывод тривиален.Может быть более сложный случай, когда логический вывод <> не так тривиален, его проверка типов может быть полезной, чего не хватает в исходной версии.

class Foo<T>
{
    Foo(Class<T> clazz){}
}

Foo<String> foo1 = new Foo(Integer.class);    // compiles (wrongly) 

Foo<String> foo2 = new Foo<>(Integer.class);  // does not compile
0 голосов
/ 04 ноября 2011

На самом деле это не требуется.Если вы наберете

Set<String> s = new HashSet();

, код скомпилируется, и мы получим предупреждение, которое мы можем проверить с помощью Xlint.

Note: filetest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

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

0 голосов
/ 04 ноября 2011

Java 7 обращается к добавлению ограниченного вывода типа для выражения создания экземпляра класса. В тех случаях, когда параметризованные типы должны быть явно объявлены для конструктор и полный параметризованный тип из этот конструктор очевиден из контекста, а затем Тип конструктора можно заменить на пустой набор типов параметры: <>. Конструкция <> допустима при создании объект и либо присвоение его переменной, либо при передаче его как параметр.

Подробнее: нажмите здесь

...