Вложенность универсальных типов Java

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

Почему не работает второй способ?

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}

Как вы хотите использовать параметры типа в методах?

ernest_k 20.04.2018 15:53

Внутри N является параметром при добавлении узла и типом возвращаемого значения при запросе узлов, а E отображает узлы в хэш-карте и используется для запроса графа.

Michael 20.04.2018 16:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В контексте дженериков Java слово расширяет означает верхний граница, а не наследование. Значение этого слова перегружено в случае дженериков.

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

Во время компиляции общие типы стираются и заменяются фактическими границами (https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html). И вот основная причина вашей проблемы. Если предоставленная граница также является универсальной, компилятор не может выполнить стирание типа. Он просто не знает, каким типом он должен заменить общий в коде во время компиляции. Так вы получите ошибку компиляции.

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

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

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}

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

Также вот несколько полезных ресурсов о дженериках: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.htmlhttps://docs.oracle.com/javase/tutorial/java/generics/index.html

Первый действительно отличный. Вот информация о слове extends и его значении в контексте обобщения: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Does%20extends%20always%20mean%20inheritance?

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

Michael 21.04.2018 06:29

Другие вопросы по теме

Похожие вопросы

Как применить шаблон дизайна моста, если разработчик должен точно знать, какую абстракцию реализовать?
Использовать сгенерированные декларативной моделью классы Drools в качестве основной бизнес-объектной модели
Какое сочетание клавиш Intellij позволяет перейти в начало / конец списка аргументов (заключено в закругленные скобки)?
Я хочу преобразовать «08:30:00» в P00DT08H30M. как лучше всего преобразовать в желаемый результат в Java?
Как анимировать TextView с помощью индикатора выполнения
ForName вернул значение как Тип
Apache Ignite JDBC и стратегия кэширования с отложенной записью с сохранением сторонних поставщиков
JAX-RS скомпилирован для JAVA 1.5 .. Я пытаюсь создать REST-клиент здесь .. Если да, то какая версия совместима с ним?
Индикатор выполнения между действиями android studio
Проверьте, существует ли пользователь в базе данных Firebase на нескольких дочерних узлах