所以我有了这个超级令人兴奋的Java课程:
import scala.collection.immutable.Stream;
public class EmptyStreamFactory {
public static Stream<String> createEmptyStringStream() {
return Stream.<String>empty();
}
}
使用类路径上的2.10.4 scala-library.jar
进行编译(或2.9.2,这是值得的)。现在我用2.11尝试:
EmptyStreamFactory.java:5: error: incompatible types
return Stream.<String>empty();
^
required: Stream<String>
found: GenTraversable
1 error
这有什么意义呢?乍看之下唯一可能与远程相关的差异是Stream.Empty
不再在2.11中扩展Serializable
这一事实,但我不知道这会如何导致这个问题。 List
等也会发生同样的事情。
有一个简单的解决方法 - 您可以投射到合适的类型 - 但我想了解这里发生了什么。
(我使用的是Oracle的JDK,版本1.7.0_67。)
答案 0 :(得分:4)
bridge方法的静态转发器本身没有标记为桥接方法,而java无论出于何种原因都喜欢返回GenTraversable,因为它有两个可供选择。
classOf[scala.collection.immutable.Stream[_]].getMethods filterNot
(_.isBridge) filter (_.getName == "empty") foreach println
public static scala.collection.immutable.Stream scala.collection.immutable.Stream.empty()
public static scala.collection.GenTraversable scala.collection.immutable.Stream.empty()
你不能在java语言中重载返回类型,所以任何人都猜测编译器在遇到它时会做什么。我不知道它是否被指定,尽管它可能是。
一般情况下你can't call collections methods from java,这被判断为wontfix。
编辑:重新“仍然不明白2.11中发生了什么变化才能实现这一目标”,这里是最初的一批候选人:
% git log --no-merges --oneline --grep=forwarder v2.10.4..v2.11.2
532ef331eb (pull/3868/head) Restore reporter forwarders in CompilationUnit
b724201383 Rip out reporting indirection from CompilationUnit
98216be3f3 Move reporting logic into Reporting trait
653c404d7f (pull/3493/head) SI-3452 GenBCode version of the static-forwarder signature fix
640e279500 SI-3452 A better fix for static forwarder generic sigs
f8d80ea26a SI-3452 Correct Java generic signatures for mixins, static forwarders
51ec62a8c3 (pull/3480/head) SI-6948 Make the Abstract* classes public.
731ed385de SI-8134 SI-5954 Fix companions in package object under separate comp.
3cc99d7b4a (pull/3103/head) Collections library tidying and deprecation. Separate parts are listed below.
5d29697365 Flesh out the Delambdafy phase.
6e2cadb8bd (pull/2951/head) SI-7847 Static forwarders for case apply/unapply
9733f56c87 (pull/1173/head) Fixes SI-4996.
你不会通过查看库代码找到它,这是肯定的。这是编译器的一个变化。
答案 1 :(得分:2)
我今天学到的是Java很乐意忽略一个无关的类型arg(JLS 15.12.2.1,本节末尾的精细打印)。
这条规则源于兼容性和原则的问题 可替代性。
显然,一些规则源于原则性推理,其他规则源于实际问题,偶尔的规则具有双重父母身份。
apm@mara:~/tmp$ javap -classpath ~/scala-2.11.2/lib/scala-library.jar scala.collection.immutable.Stream | grep empty
public static <A extends java/lang/Object> scala.collection.immutable.Stream<A> empty();
public static scala.collection.GenTraversable empty();
apm@mara:~/tmp$ javap -classpath ~/scala-2.10.4/lib/scala-library.jar scala.collection.immutable.Stream | grep empty
public static <A extends java/lang/Object> scala.collection.immutable.Stream<A> empty();
public static <A extends java/lang/Object> scala.collection.immutable.Stream<A> empty();
看起来桥方法的转发器已修复。
编译:
import scala.collection.immutable.Stream;
import scala.collection.immutable.Stream$;
public class EmptyStreamFactory {
public static Stream<String> createEmptyStringStream() {
return Stream$.MODULE$.<String>empty();
}
}
我需要一个为期三天的周末来重新阅读Java中的重载规范。
也许因为Stream是抽象的,大多数特定返回类型规则的规则都会启动。