Подтвердить что ты не робот

Оператор алмаза <> эквивалентен <?>

Я нашел в классе util.TreeSet, что один из конструкторов вызывает другой конструктор с новым TreeMap с пустым родовым типом.

  public TreeSet(Comparator<? super E> comparator) {
         this(new TreeMap<>(comparator));
  }

Что означает new TreeMap<>? эквивалентно new TreeMap<?>?

4b9b3361

Ответ 1

Это синтаксис Java 7. Алмаз (<>) является кратким, чтобы попросить компилятор Java заполнить общие аргументы тем, что имеет смысл в локальном контексте (в этом случае это будет ? super E).

Ответ 2

Нет, <?> и <> не совпадают.

<?> является "неограниченным подстановочным знаком" и существует со времени Java 5. Этот шаблон позволяет (то есть соответствует) все, что позволяет связать тип, без каких-либо дополнительных ограничений. Подстановочные знаки выходят за счет операций, которые вы можете выполнить на общем экземпляре. Для получения дополнительной информации о подстановочных знаках прочитайте раздел java tutorial. Чтобы узнать, какие подстановочные знаки разрешены с ограничениями типа, проверьте этот блог.

"<>", оператор алмаза, был добавлен в Java 7. Цель заключалась в том, чтобы разработчики не нуждались в излишней детализации при создании экземпляров родовых типов, поскольку компилятор выводил эти типы из контекста при вызове конструктора.

Компилятор запрашивает наиболее специфичные типы (ы), факторинг в следующих случаях:

1- Типы аргументов, переданных конструктору.

2- Типы, которые вы указываете в ссылке, которой назначен новый экземпляр (слева часть задания '=').

3- Стирание для типов.

В вашем примере компилятор заменит new TreeMap<>(comparator) на new TreeMap<E,Object>(comparator).

Чтобы понять, почему, посмотрите на конструктор для TreeMap<K,V>, который вызывается: TreeMap(Comparator<? super K> comparator).

компилятору необходимо вывести типы для K и V. Он ожидает Comparator<? super K> и находит передаваемый Comparator<? super E>, без назначения левой руки, и у компилятора не будет проблемы с E, назначаемой K (все, что соответствует E, будет соответствовать K, так как они имеют одно и то же стирание), он заключает, что K= E.

Для V снова нет назначения левой руки, нет параметров для того, что передано конструктору, поэтому оно остается с стиранием для типа V, как указано в TreeMap<K,V> со стиранием до Object, поэтому сделаем вывод, что V= Object.

Там у вас есть, компилятор выводит K= E и V= Object, и оператор становится TreeMap<E,Object>(comparator).

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