Ошибка компиляции Java с интерфейсами - PullRequest
2 голосов
/ 12 августа 2010

Я получаю следующее сообщение об ошибке (сокращено до важной части) при компиляции моих классов:

reference to keySet is ambiguous, both method keySet() in
java.util.SortedMap<E,capture#614 of ?> and method keySet() in
test.ImmutableMap<E,capture#614 of ?> match
    return map.keySet().iterator();
              ^

map имеет тип ImmutableSortedMap<E, ?> иОпределение неизменяемых классов выглядит следующим образом:

public interface ImmutableMap<K, V>
    extends Map<K, V> {
  @Override
  public ImmutableSet<K> keySet();
  ...
}
public interface ImmutableSortedMap<K, V>
    extends ImmutableMap<K, V>, SortedMap<K, V> {
  ...
}
public interface ImmutableSet<E>
    extends Set<E> {
  ...
}

Ошибка появляется, когда я компилирую с использованием сценария ANT или вручную, но не в Eclipse.Я пробовал это с sun 1.6.0 и icedtea6 1.8.1 .

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


РЕДАКТИРОВАТЬ: ответ

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

public interface ImmutableSortedMap<K, V>
    extends ImmutableMap<K, V>, SortedMap<K, V> {
  // adding this method solves the problem
  @Override
  public ImmutableSet<K> keySet();
}

Кстати, это и есть Diamonпроблема.

Ответы [ 2 ]

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

Мне кажется, ImmutableMap#keySet имеет неправильный тип возврата. Это должно быть Set<K> или ImmutableSet<K>.
Или, если вы хотите вернуть набор пар, переопределите Map#entrySet.

В этом нет ничего плохого, если взаимодействие A расширяет интерфейсы B и C, а у B и C есть метод с одинаковой сигнатурой (doIt(String param1, int param2)). Но типы возврата B#doIt и C#doIt должны быть совместимы. Если B#doIt возвращает String, а C#doIt возвращает int, то мы не можем объединить эти два метода в одном классе.

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

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

оба интерфейса ImmutableMap и SortedMap имеют метод с именем "keySet ()", поэтому компилятор не может определить, какой из них вызвать.Измените имя метода в вашем интерфейсе;)

...