Подтвердить что ты не робот

Почему это компилируется под Java 7, но не под Java 8?

Это похоже на компиляцию с Java 7 и любой версией библиотек Scala:

public static void main(String[] args) {
    scala.collection.immutable.Set<String> set = new scala.collection.immutable.HashSet<String>();
    Iterator<String> iterator = set.iterator();
}

Он также отлично компилируется с Java 8 и Scala 2.11.5+. Но с Java 8 и Scala 2.11.4 Eclipse жалуется:

The method iterator() is ambiguous for the type Set<String>

Я не понимаю этого. Вы можете получить двусмысленность относительно того, какой перегруженный метод выбрать в некоторых контекстах, но, конечно же, если вы не передаете какие-либо аргументы?

Самое странное, что если я переделаю его так:

public static void main(String[] args) {
    Iterator<String> iterator = new scala.collection.immutable.HashSet<String>().iterator();
}

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

4b9b3361

Ответ 1

Если мы сравним вывод javap scala.collection.immutable.Set, мы получим для 2.11.4:

public interface scala.collection.immutable.Set<A> 
    extends 
        scala.collection.immutable.Iterable<A>, 
        scala.collection.Set<A>, 
        scala.collection.generic.GenericSetTemplate<A, 
        scala.collection.immutable.Set>, 
        scala.collection.SetLike<A, scala.collection.immutable.Set<A>>, 
        scala.collection.Parallelizable<A, 
        scala.collection.parallel.immutable.ParSet<A>> {
    public abstract scala.collection.generic.GenericCompanion<scala.collection.immutable.Set> companion();
    public abstract <B> scala.collection.immutable.Set<B> toSet();
    public abstract scala.collection.immutable.Set<A> seq();
    public abstract scala.collection.parallel.Combiner<A, scala.collection.parallel.immutable.ParSet<A>> parCombiner();
}

и для 2.11.5:

public interface scala.collection.immutable.Set<A>
    extends 
        scala.collection.immutable.Iterable<A>, 
        scala.collection.Set<A> {
    public abstract scala.collection.generic.GenericCompanion<scala.collection.immutable.Set> companion();
    public abstract <B> scala.collection.immutable.Set<B> toSet();
    public abstract scala.collection.immutable.Set<A> seq();
    public abstract scala.collection.parallel.Combiner<A, scala.collection.parallel.immutable.ParSet<A>> parCombiner();
}

Версия 2.11.4 неверна, это является нарушением спецификации виртуальной машины Java, раздел 4.7.9.1:

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


Это ясно объясняется в этой проблеме с скаляром, которые были исправлены в... 2.11.5