Когда вывод типа Java создает бесконечный тип? - PullRequest
11 голосов
/ 10 августа 2010

JLS упоминает в алгоритме вывода типа (§15.12.2):

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

Однако я не могу найти фактический пример, где javac создает бесконечный тип.Я думаю, что он должен произвести один в следующем случае:

<T> T pick(T a, T b) { ... }

pick("string", 3);

И String, и Integer являются сопоставимыми , поэтому их общий супертип должен быть Comparable<? extends Comparable<? extends Comparable<? ...>>> (бесконечный).Я могу сделать:

Comparable<? extends Comparable<?>> x = pick("string", 3);

но затем я попытался:

Comparable<? extends Comparable<? extends Comparable<?>>> x = pick("string", 3);

, и это не скомпилируется.Кажется, что рекурсия прерывается через 2 шага.

Вам известен какой-либо случай, когда Java на самом деле создает бесконечный тип?

-

Редактировать: кажетсячто вышеупомянутое является ошибкой компилятора.Читая спецификацию, давайте посмотрим, как работает вычисление lub(String, Integer):

ST(String) = { String, Comparable<String>, Serializable, CharSequence, Object }
ST(Integer) = { Integer, Comparable<Integer>, Serializable, Number, Object }
EC = { Comparable, Serializable, Object }
MEC = { Comparable, Serializable }
Inv(Comparable) = { Comparable<String>, Comparable<Integer> }
lcta(String, Integer) = ? extends lub(String, Integer)
lci(Inv(Comparable)) = Comparable<? extends lub(String, Integer)>
lub(String, Integer) = Serializable & Comparable<? extends lub(String, Integer)>

Так что lub(String, Integer) должен быть бесконечного типа.Джавак, кажется, здесь не так.Может быть, он не реализует бесконечные типы в конце концов?

Ответы [ 2 ]

9 голосов
/ 12 августа 2010

Следующий код отправляет javac в бесконечный цикл.Предположительно, он пытается построить бесконечный тип, но ему не удается представить его как конечную циклическую структуру данных.

interface I<T> {}
interface A<T> extends I<A<A<T>>>{}
abstract class X {
    abstract <T> T foo(T x, T y);

    void bar(A<Integer> x, A<String> y){
        foo(x, y);
    }
}
0 голосов
/ 10 августа 2010

Возможны бесконечные типы (например, объект Map внутри карты внутри карты и т. Д. .....

Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map>>>>> objectMap;

(Это сделано для глубины 5 для удобства чтения ... но вы можете добавлять карты внутри карты бесконечно глубоко.

Я не знаю, если это то, что вы ищете ....

...