2010-08-10 1 views
11

ПСБ упоминает в алгоритме вывода типов (§15.12.2):Когда вывод типа Java создает бесконечный тип?

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

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

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

pick("string", 3); 

Обе строки и Integer является Сопоставимыми < themselve>, так что их общий супертип должен быть Comparable<? extends Comparable<? extends Comparable<? ...>>> (бесконечность).

я могу сделать:

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

но потом я попробовал:

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

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

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

-

Edit: мне кажется, что выше ошибка компилятора. Чтение спецификации, давайте посмотрим, как расчет 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) должен быть бесконечным типом. Кажется, Джавак здесь не прав. Может быть, он не реализует бесконечные типы в конце концов?

+1

Имейте в виду последнюю часть вашей цитаты: «... Java-компиляторы должны распознавать такие ситуации и представлять их соответствующим образом ...». Любой компилятор, который соответствует спецификациям, даже не будет мигать, если вы передадите ему «бесконечный тип». Добавьте стирание стилей в микс, и все в вашем примере просто превратится в Comparable или Object. Поэтому, если вы не строите компилятор Java, вы, вероятно, даже не заметите. – cHao

+0

@cHao: Похоже, что javac от Sun не соответствует спецификации. Я не смог создать с ним бесконечный тип, поэтому я задаю этот вопрос. Похоже, они просто оставили эту языковую функцию нереализованной. – Daniel

ответ

10

следующий код посылает 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

Очень хороший пример! –

+1

Я думаю, что этот пример является примером «экспансивного наследования». Экспансивное наследование включает бесконечный цикл, создающий бесконечную серию типов (каждый больше, чем предыдущий). Но каждый задействуемый тип конечен, поэтому на самом деле это не вопрос. (Я подозреваю, что вопрос неопровержимый, потому что javac фактически не реализует бесконечные типы) – Daniel

0

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

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

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

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

+1

Итак, как вы производите такой тип? Его нельзя назвать (потребуется бесконечный исходный файл), поэтому он может возникать только в результате вывода типа.Я ищу пример вызова метода, где Java передает такой бесконечный тип. – Daniel

+0

Вам нужно будет сделать это рефлексивно .... –

+0

Отражение не сможет получить параметры типа - они исчезли, когда компиляция закончится. «Бесконечные типы» применимы только во время компиляции, а не раньше (вывод типа создает их и обрабатывает их более или менее прозрачно), а не после (стирание типа избавляется от параметров типа, превращая бесконечный тип в обычный тип как Объект). – cHao

 Смежные вопросы

  • Нет связанных вопросов^_^