如何让Scala代码与Java库互操作?

3

我有一个Java库需要在Scala中使用/调用。这个Java库的签名如下:

JavaFunction( List<Object[]> data) {
  this.data = data;
}

我以为要与Scala兼容,需要有一个AnyRef对象,所以我定义了以下内容:

  val fromScala: List[Array[AnyRef]] = List(
    Array[AnyRef](1, "Str1", 'a'),
    Array[AnyRef](2, "Str2", 'b'),
    Array[AnyRef](3, "Str3", 'c'),
    Array[AnyRef](4, "Str4", 'd')
  )

我试图将这个内容传给构造函数时,在编译时遇到了以下错误:

the result type of an implicit conversion must be more specific than AnyRef
    Array[AnyRef](1,  "Str1", 'a')

我明白编译器希望我在类型方面更加明确,但我没有看到其他解决此问题的方式。有什么想法吗?

1个回答

1
问题在于这些数字 1AnyVal类型,而不是AnyRef类型,因此会在幕后进行隐式转换。
您可以使用 Int.box(1) 创建一个java.lang.Integer对象。
但是,这种装箱操作仍然会在运行时发生,因此您只是添加了样板代码。您可以尝试看看List[Array[Any]]是否能够编译并按预期工作。

非常准确!但我认为AnyRef是Scala中Java的Object的等效物,这让我想到应该使用AnyRef而不是Any。 - joesan
据我所知,从技术上讲是可以的,但是 Any 也必须擦除;但我不确定,也无法测试。我很高兴它能够工作 :D - Luis Miguel Mejía Suárez
2
有点复杂 - AnyRef 涵盖了除了原始类型包装器和 void 对应项(UnitAnyVal)以外的所有 Object。这是因为 AnyVal 根据上下文被转换为原始类型或包装器。所以当你与 Java 交互时,你应该手动将你的类型转换为 Java 类型 - AnyValAnyRef 不是 100% 可映射到原始类型或 Object,所以最好自己进行转换或使用 Any 并让 Scala 决定。 - Mateusz Kubuszok

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接