为什么这是在Java 7下编译而不是在Java 8下编译?

时间:2015-05-21 11:18:48

标签: java scala compiler-errors java-8 scala-collections

这似乎可以使用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();
}
然后投诉就消失了。在我看来,这与上面的版本完全相同。那么为什么它现在编译好了呢?

2 个答案:

答案 0 :(得分:10)

如果我们比较scala.collection.immutable.Set的javap输出,我们得到的是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虚拟机规范section 4.7.9.1

  

类签名对有关(可能是通用的)类声明的类型信息进行编码。它描述了类的任何类型参数,并列出了其(可能参数化的)直接超类和直接超级接口(如果有)。类型参数由其名称描述,后跟任何类绑定和接口边界。

这在this scalac issue中有明确解释,已在...... 2.11.5

中修复

答案 1 :(得分:6)

这可能不是严格的Java 8 / Scala库问题。它可能与Eclipse有关。您使用的是哪个版本的Eclipse?这听起来有点像Eclipse 4.4中的这个问题:Java 8 generics thinks single method is ambiguous