Scala 删除通用类型信息
Scala Removing Generic Type Information
我有一个正在生成 jar 的 scala 项目。我正在尝试在 Java 项目中使用该 jar。奇怪的是方法签名在编译为 .class 文件时会丢失通用类型信息。
def foo(x:List[Long]) = ...
用
生成一个方法
Lscala/collection/immutable/List<Ljava/lang/Object;>
在其 .class 文件中。
和
一样
def foo(x:java.util.List[Long]) = ...
.class 文件说方法签名是
Ljava/util/List<Ljava/lang/Object;>
真正的问题是,当我在 Java 项目中使用这个 jar 时,我必须使用 List<Object>
而不是我想要的 List<Long>
。当然我可以施法,但我宁愿不必施法。有什么想法吗?
我正在使用 scala 版本 2.11.7
如果您希望您的方法能够以您想要的方式从 Java 调用,您必须将其声明为采用 List[java.lang.Long]
.
为什么?那么,scala.Long
相当于 Java 的 long
,而不是 Java 的 java.lang.Long
。并且在 Java 类型系统中,类型参数可能不引用原始类型,只能引用类型。因此 Scala 无法发出 "correct" 签名并被迫退回到 java.lang.Object
.
(在非常旧的 Scala 版本中,它曾经回退到 java.lang.Long
,但不幸的是,这实际上不是 100% 正确的解决方案,并导致了一系列互操作问题。参见 https://issues.scala-lang.org/browse/SI-4214 血淋淋的细节。不幸的是,我不知道更简洁的文章。这种情况经常出现,所以如果有这样的文章,我想知道。)
我有一个正在生成 jar 的 scala 项目。我正在尝试在 Java 项目中使用该 jar。奇怪的是方法签名在编译为 .class 文件时会丢失通用类型信息。
def foo(x:List[Long]) = ...
用
生成一个方法
Lscala/collection/immutable/List<Ljava/lang/Object;>
在其 .class 文件中。
和
一样def foo(x:java.util.List[Long]) = ...
.class 文件说方法签名是
Ljava/util/List<Ljava/lang/Object;>
真正的问题是,当我在 Java 项目中使用这个 jar 时,我必须使用 List<Object>
而不是我想要的 List<Long>
。当然我可以施法,但我宁愿不必施法。有什么想法吗?
我正在使用 scala 版本 2.11.7
如果您希望您的方法能够以您想要的方式从 Java 调用,您必须将其声明为采用 List[java.lang.Long]
.
为什么?那么,scala.Long
相当于 Java 的 long
,而不是 Java 的 java.lang.Long
。并且在 Java 类型系统中,类型参数可能不引用原始类型,只能引用类型。因此 Scala 无法发出 "correct" 签名并被迫退回到 java.lang.Object
.
(在非常旧的 Scala 版本中,它曾经回退到 java.lang.Long
,但不幸的是,这实际上不是 100% 正确的解决方案,并导致了一系列互操作问题。参见 https://issues.scala-lang.org/browse/SI-4214 血淋淋的细节。不幸的是,我不知道更简洁的文章。这种情况经常出现,所以如果有这样的文章,我想知道。)