Возможная ошибка компилятора Java! Программа не компилируется с некоторыми компиляторами

Во-первых, немного фона (или пропустите немного, если не интересно). Я раздражен и смущен! Это должен быть довольно простой случай использования, и действительно, мой код очень хорошо компилируется с помощью компилятора Eclipse JDT, поэтому до сих пор я настраивал Maven, чтобы убедиться в этом. Это слишком беспокоило меня, хотя оно не компилируется с Oracle JDK и OpenJDK, поскольку я думал, что это может быть проблемой с моим кодом, поэтому я снова просмотрел его.

Я подумал, что, возможно, ошибка была в компиляторе JDT, позволяющем компилировать его, а не Oracle JDK и OpenJDK для того, чтобы не разрешать это, оба из которых я также тестировал. Исходный код, о котором идет речь, был значительно сложнее, поэтому мне было гораздо труднее понять, в чем проблема, и на самом деле я был очень удивлен, увидев, насколько это может быть уменьшено, пока он еще не компилируется.

У компилятора Eclipse JDT или Oracle JDK и OpenJDK есть довольно серьезная ошибка (imho).

TL; DR

Это довольно минимальное представление рассматриваемого кода. (Ограничение типа Anything может быть заменено любым интерфейсом, и поведение компилятора не изменится):

public class Bug<X extends Property<?, ?> & Anything> {
}

interface Property<C, S extends C> extends PropertyConst<C> {
    @Override
    public S get();
}

interface PropertyConst<C> {
    public C get();
}

interface Anything {
}

Подводя итог, я думаю, что это должно скомпилировать просто отлично, но Oracle JDK 7 и 8 и OpenJDK 7 не согласны. Он компилируется для меня с помощью Eclipse Juno.

При компиляции с любым из этих компиляторов код выше дает что-то вроде следующей ошибки, но отлично работает с компилятором JDT:

Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
                 ^
1 error

Это не имеет смысла. Типы возврата, очевидно, связаны с тем, что один из двух методов, на которые ссылаются, обязательно frickin 'переопределяет другой. Я почти на 99% уверен, что это должно сработать, на самом деле единственная причина, по которой последние 1% отсутствует, заключается в том, что просто слишком простое использование дженериков для этого не было замечено, и все же я не нашел отчета об ошибке к нему. (По общему признанию, я не выглядел тяжело, потому что http://bugs.sun.com/ - это самое худшее. Можете ли вы даже фильтровать результаты поиска по ключевым словам, все еще открыт?).

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

Может ли кто-нибудь успокоить мой разум? Кто-нибудь знает отчет об ошибке, который существует для этого, или имел опыт работы с ним раньше и может рассказать мне, в чем проблема? Если я не получу никаких окончательных ответов, я напишу несколько отчетов об ошибках.

Edit:

Несколько человек указали, что у меня была ошибка прямого сравнения с < S extends C, C > . Не знаю, почему я не получал эту ошибку, она даже скомпилирована в Eclipse с помощью JDT...

Во всяком случае, он по-прежнему не компилируется для меня с OpenJDK 7 или Oracle JDK 7/8, поэтому я изменил вопрос, чтобы устранить проблему.

Изменить 2:

Быстрая проверка подтверждает, что этот вид прямой ссылки теперь легален в Java 7. Как и должно быть!

Изменить 3:

Я опубликовал отчеты об ошибках http://bugs.sun.com/. Я буду размещать ссылки здесь, если/когда они будут приняты.

Ответ 1

По-видимому, это ошибка javac, о которой вы должны сообщить. Вероятно, вам лучше повезти в одном из открытых списков рассылки jdk. Но это благодарение, так что...

Это не основное использование дженериков, но это довольно сложно.

Ответ 2

Я ввел ваш образец в свой Eclipse Indigo (3.7.1), и он сразу же пожаловался на объявление интерфейса Property.

Недопустимая обратная ссылка на параметр типа C

И для строки public S get();

Возвращаемый тип несовместим с PropertyConst.get()

Изменение объявления Property к этому

interface Property<C, S extends C > extends PropertyConst<C> {
    @Override
    public S get();
}

исправлены обе ошибки и компилируются как в JDT, так и в компиляторе Sun 1.6

Ответ 3

Не пробовал, но в

public class Bug<X extends Property<?, ?> & Anything> {

не существует сдержанности как для ?. Нужно было что-то вроде:

public class Bug<C, X extends Property<C, ? extends C> & Anything> {