У меня здесь довольно сложный случай с дженериками и перегрузкой методов. Посмотрите этот пример класса:
public class Test {
public void setValue(Parameter parameter, T value) {
}
public void setValue(Parameter parameter, Field value) {
}
public void test() {
// This works perfectly. is bound to String
// ambiguity between setValue(.., String) and setValue(.., Field)
// is impossible as String and Field are incompatible
Parameter p1 = getP1();
Field f1 = getF1();
setValue(p1, f1);
// This causes issues. is bound to Object
// ambiguity between setValue(.., Object) and setValue(.., Field)
// is possible as Object and Field are compatible
Parameter
Приведенный выше пример отлично компилируется в Eclipse (Java 1.6), но не с помощью команды Ant javac (или команды javac JDK), где я получаю такое сообщение об ошибке при втором вызове setValue :
ссылка на setValue неоднозначна,
оба метода
setValue (org.jooq.Parameter, T)
in Тест и метод
setValue (org.jooq.Parameter, org.jooq.Field)
in Test match
В любом случае, даже если привязан к Object , оба метода setValue являются приемлемыми кандидатами. для вызова вариант с параметром Поле всегда кажется более конкретным. И он работает в Eclipse, но не с компилятором JDK.
UPDATE :
Таким образом, он будет работать как в Eclipse, так и с компилятором JDK (конечно, с предупреждениями о rawtypes). Я понимаю, что правила, указанные в спецификациях , довольно специфичны, когда речь идет о дженериках. Но я нахожу это довольно запутанным:
public void setValue(Parameter parameter, Object value) {
}
// Here, it's easy to see that this method is more specific
public void setValue(Parameter parameter, Field value) {
}
ОБНОВЛЕНИЕ 2 :
Даже с универсальными шаблонами я могу создать обходной путь, позволяющий избежать привязки типа к Object во время вызова setValue путем добавления дополнительной однозначной косвенной адресации, называемой setValue0 . Это заставляет меня думать, что привязка T к объекту действительно является причиной всех проблем:
public void setValue(Parameter parameter, T value) {
}
public void setValue(Parameter parameter, Field value) {
}
public void setValue0(Parameter parameter, Field value) {
// This call wasn't ambiguous in Java 7
// It is now ambiguous in Java 8!
setValue(parameter, value);
}
public void test() {
Parameter p2 = p2();
Field f2 = f2();
setValue0(p2, f2);
}
Я что-то не понимаю? Связана ли с этим известная ошибка компилятора? Или есть обходной путь / настройка компилятора, которые могут мне помочь?
Продолжение:
Для тех, кто заинтересован, я отправил отчет об ошибке как в Oracle, так и в Eclipse. Oracle приняла ошибку, Eclipse проанализировал ее и отклонил! Похоже, моя интуиция верна, и это ошибка в javac