Reputation: 20520
This seems to compile fine with Java 7, and any version of the Scala libraries:
public static void main(String[] args) {
scala.collection.immutable.Set<String> set = new scala.collection.immutable.HashSet<String>();
Iterator<String> iterator = set.iterator();
}
It also compiles fine with Java 8 and Scala 2.11.5+. But with Java 8 and Scala 2.11.4, Eclipse complains:
The method iterator() is ambiguous for the type Set<String>
I don't understand this. You might get ambiguity over which overloaded method to select in some contexts, but surely not if you're not passing any arguments?
The really weird thing is that if I recast it like this:
public static void main(String[] args) {
Iterator<String> iterator = new scala.collection.immutable.HashSet<String>().iterator();
}
then the complaint goes away. This seems to me to be exactly equivalent to the version above. So why would it now compile fine?
Upvotes: 20
Views: 3148
Reputation: 29540
If we compare the javap output of scala.collection.immutable.Set
, we get for the 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();
}
and for the 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();
}
The version 2.11.4 is not correct, it is a violation of the Java Virtual Machine Specification, section 4.7.9.1:
A class signature encodes type information about a (possibly generic) class declaration. It describes any type parameters of the class, and lists its (possibly parameterized) direct superclass and direct superinterfaces, if any. A type parameter is described by its name, followed by any class bound and interface bounds.
This is clearly explained in this scalac issue, which have been fixed in the... 2.11.5
Upvotes: 10
Reputation: 6362
This may not be a strictly Java 8/Scala library issue. It may be related to Eclipse. Which version of Eclipse are you using? This sounds somewhat like this issue in Eclipse 4.4: Java 8 generics thinks single method is ambiguous
Upvotes: 7