2

我有一个生成 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

4

1 回答 1

5

如果您希望您的方法能够以您想要的方式从 Java 调用,您必须将其声明为采用List[java.lang.Long].

为什么?嗯,scala.Long相当于 Java 的long,而不是 Java 的java.lang.Long. 而且在Java类型系统中,类型参数可能不是指原始类型,而是引用类型。所以 Scala 不能发出“正确”的签名并被迫回退到java.lang.Object.

(在非常旧的 Scala 版本中,它曾经回退到java.lang.Long,但不幸的是,这实际上并不是 100% 正确的解决方案,并导致了一堆互操作问题。请参阅https://issues.scala-lang.org/browse /SI-4214获取血腥细节。不幸的是,我不知道更简洁的文章。这经常出现,所以如果有这样的文章,我想知道。)

于 2015-10-20T18:01:07.710 回答