我有一个正在生成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不能发出"正确的"签名,并被迫返回到java.lang.Object
。
(在非常老的Scala版本中,它曾经退回到java.lang.Long
,但不幸的是,这实际上不是一个100%正确的解决方案,并导致了一堆互操作问题。请参阅https://issues.scala-lang.org/browse/SI-4214了解详细信息。不幸的是,我不知道有比这更简洁的描述了。这是很常见的,所以如果有这样的文章,我想知道它