Компиляторы ведут себя по-другому с пустым параметром общего метода

Следующий код компилирует отлично с Eclipse, но сбоями для компиляции с javac:

public class HowBizarre {
      public static <P extends Number, T extends P> void doIt(P value) {
      }

      public static void main(String[] args) {
            doIt(null);
      }
}

Я упростил код, таким образом, T не используется вообще теперь. Однако, я не вижу оснований для ошибки. По некоторым причинам javac решает, что T обозначает Объект и затем жалуется, что Объект не соответствует границам T (который верен):

HowBizarre.java:6: несовместимые типы; выведенный аргумент (аргументы) типа java.lang. Число, java.lang. Объект не соответствует границам переменной (переменных) типа P, T

найденный: <P,T>пусто

требуемый: пусто

       doIt(null);
           ^

Обратите внимание, что, если я заменяю пустой параметр ненулевым значением, он компилирует прекрасный.

Какой из компиляторов ведет себя правильно и почему? Действительно ли это - ошибка одного из них?

16
задан Paul Bellora 14 November 2011 в 19:47
поделиться

3 ответа

Проблема связана со спецификацией JLS, которая требует, чтобы аргументы типа, которые в противном случае не могли быть отклонены, выводились как Объект , даже если он не удовлетворяет ограничениям (и, следовательно, вызвать ошибку компиляции).

Ниже приводится отрывок из отчета об «ошибке» (который был дополнительно аннотирован для ясности):

«Ошибка» ID 6299211 - переменная типа метода: вывод прерван для null

Эта программа не компилируется:

 public class Try {
void m () {
java.util.Collections.max (ноль);
 }
}

Состояние : ЗАКРЫТО, НЕ ДЕФЕКТ.

Оценка : ЭТО НЕ ОШИБКА . Алгоритм вывода не может собрать какую-либо информацию из аргумента ( null ), и метод не вызывается там, где есть какие-либо ожидания в отношении возвращаемого значения. В таких случаях компилятор должен вывести java.lang.Object для переменной типа.


JLS 15.12.2.8 Вывод неразрешенных аргументов типа

Все оставшиеся переменные типа, которые еще не были выведены, затем считаются имеющими тип Объект


Однако Объект не является подтипом Comparable < ? super Object> и, следовательно, не входит в границы переменной типа в объявлении Collections.max :

Object & Comparable > T max (Коллекция )


Дальнейшие исследования

Использование явных параметров типа «устраняет» проблему:

HowBizarre.<Number,Integer>doIt(null); // compiles fine in javac

Чтобы показать, что это не имеет отношения к null аргумент и многое другое, связанное с абсолютным отсутствием информации для определения типа, вы можете попробовать, например, любое из следующих объявлений:

<T,U extends Comparable<T>> void doIt()

<T extends Number,U extends T> void doIt()

В любом случае вызов doIt (); не компилируется в javac , поскольку он должен выводить U для быть Объект согласно 15.12.2.8, даже если это вызовет ошибку компиляции.


Замечание по Eclipse

Хотя ни один из приведенных выше фрагментов не компилируется в некоторой версии javac , все они компилируются в некоторой версии Eclipse. Это может указывать на ошибку со стороны Eclipse. Известно, что между разными компиляторами есть разногласия.

Связанные вопросы

18
ответ дан 30 November 2019 в 21:45
поделиться

Это скорее ошибка в javac. Eclipse выводит правильный тип.

Вы можете обойти это, вызвав doIt ((Number) null);

Даже если вы не планируете использовать javac для разработки, исправьте эту проблему, потому что такие инструменты, как ant или maven, используют его и это вызовет проблемы, если вы когда-нибудь их представите.

4
ответ дан 30 November 2019 в 21:45
поделиться

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

2
ответ дан 30 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

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