Ответ 1
Это кажется довольно гнусным угловым случаем, так как существует количество ошибок, связанных с циклическим наследованием, часто приводящее к бесконечным циклам, переполнение стека и OOM в компиляторе. Вот некоторые релевантные цитаты, которые могут дать некоторое представление:
Этот пример не является законным, и это ясно изложено в предстоящем 2-е издание Спецификации языка Java. Классы одновременно связанные как наследованием, так и вложением, являются проблематичными, однако в первоначальном документе, посвященном домашнему классу, не было должным образом рассмотрено вопрос, и компиляторы до 1.3 не применяли согласованную политику. В JLS 2nd издание, правило против циклического наследования было расширено, чтобы запретить класс или интерфейс от "зависящего" от себя, прямо или косвенно. Тип зависит не только от типов, которые он распространяет или реализует, но также и от типы, которые служат квалификаторами в именах этих типов.
Два объявления класса действительно цикличны; в соответствии с JLS 8.1.4 мы имеем, что:
Foo зависит от Foo $Intf (Foo $Intf появляется в предложении инвентаря Foo)
Foo $Intf зависит от Moo $Intf (Moo $Intf появляется в предложении extends Foo $Intf)
Foo $Intf зависит от Foo (Foo появляется как определитель в предложении extends Foo $Intf)Для транзитивности мы имеем, что Foo зависит от самого себя; поэтому такой код должен быть отклонен с ошибкой времени компиляции.
Отступая назад, в JLS2 была введена зависимость прямого отношения для классов и интерфейсов, чтобы уточнить JLS1 и охватить суперклассы/суперинтерфейсы, которые являются вложенными классами (например, A.B в описании).
Эта проблема возникает из-за порядка, в котором javac выполняет атрибуцию границ переменной типа по атрибуту класса.
1) Атрибуция класса Outer < T extends Outer.Inner >
1a) Атрибуция атрибутов внешних триггеров переменной Outer type
2) Атрибуция Outer.T
2а) Приписывание триггеров Outer.T атрибуции объявленной связанной
3) Атрибуция класса Outer.Inner < S extends T >
3a) Атрибуция Outer.Inner вызывает атрибуцию переменной Outer.Inner type
4) Атрибуция Outer.Inner <S>
4a) Атрибуция Outer.Inner.S запускает атрибуцию объявленной связанной
5) Атрибуция Outer.T - это ничего, кроме возвращения типа T; как вы можете видеть, на этом этапе T bound еще не установлен на объекте, представляющем тип T.В более поздней точке для каждой переменной присваиваемого типа javac выполняет проверку, чтобы гарантировать, что граница данной переменной типа не вводит циклическое наследование. Но мы видели, что для Outer.T не установлена никакая граница; потому что это вызвано тем, что javac падает с NPE при попытке обнаружить цикл в дереве наследования, вызванный объявленной границей Outer.Inner.S.
Границы переменной типа могут относиться к классам, принадлежащим дереву циклического наследования, что заставляет процесс разрешения вводить цикл при поиске символов.
К вашему конкретному вопросу о том, "что такое проблемная зависимость?" он представляется сложным краем случая разрешения символа компиляции, а решение, введенное в JLS2, состояло в том, чтобы просто запретить циклы, введенные типами классификаторов, а также фактическими супертипами.
Другими словами, теоретически это можно было бы сделать с соответствующими улучшениями в компиляторе, но пока кто-то не придет и сделает это более практичным, просто запретите это необычное отношение в спецификации языка.