我在编译课程时收到以下错误消息(简称为重要部分):
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 尝试了它。
是否有一些明显我缺少的东西,或者是否有一个可以在eclipse中设置的选项以允许编译? 问题是,现在,我可以在eclipse中运行测试,但我无法在eclipse之外编译项目。
编辑:答案
似乎某些编译器版本存在多重继承问题。 解决方案是在从具有公共超级接口的其他接口继承的子类中再次覆盖该方法,并且自己覆盖该方法。
public interface ImmutableSortedMap<K, V>
extends ImmutableMap<K, V>, SortedMap<K, V> {
// adding this method solves the problem
@Override
public ImmutableSet<K> keySet();
}
顺便说一下,这是diamon问题。
答案 0 :(得分:1)
在我看来,ImmutableMap#keySet
的回复类型错误。它应该是Set<K>
或ImmutableSet<K>
或者,如果要返回一组对,请改为覆盖Map#entrySet
。
如果interace A扩展接口B和C并且B和C都具有相同签名(doIt(String param1, int param2)
)的方法,则没有错。但B#doIt
和C#doIt
的返回类型应该是兼容的。如果B#doIt
返回String并且C#doIt
返回int,那么我们不能将这两个方法组合在一个类中。
哦,不知道为什么它会在Eclipse下编译。
答案 1 :(得分:0)
两个接口ImmutableMap和SortedMap都有一个名为“keySet()”的方法,因此编译器无法找出要调用的方法。在界面中更改方法的名称;)