14

我可以在 Java 中使用 scala List,例如:

import scala.collection.immutable.List;
class HelloScalaList {
    public static void main (String[] args) {
        List xs = List(1, 2, 3);
        System.out.println(xs);
    }
}

它似乎没有编译。找不到 List$.apply 方法。

当我将其更改为

List xs = Dir.ls()

其中 Dir 是我的 scala 类,并且 ls() 返回一个 scala 列表,编译器抱怨

“内部编译器错误:java.lang.ClassCastException:org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding 无法在 org.eclipse.jdt.internal 中转换为 org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding。 compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:927)"

我不知道这意味着什么。


我想在 scala 中编写一些库,但也希望它可以在 Java 中使用。

在我的 scala 类中有返回 scala 列表的方法,对于使用它们的 java 代码,我有两个选择:

  1. 直接在java中使用scala List

  2. 编写一个为这些方法返回 java.util.List 的包装类。

我更喜欢选项 1,否则我将不得不为几乎所有的 scala 类编写一个包装类。

但我就是无法让 scala List 在 Java 中运行。

4

3 回答 3

18

Scala 2.10开始,我没有成功使用上述技巧。

但是您可以使用以下代码:

  public static <T> scala.collection.immutable.List<T> scalaList(List<T> javaList) {
    return scala.collection.JavaConversions.asScalaIterable(javaList).toList();
  }
于 2013-07-16T15:28:32.807 回答
14

一个小的 java 端辅助方法可以解决问题:

import scala.collection.immutable.List;
import scala.collection.immutable.List$;
import scala.collection.immutable.$colon$colon;

public class HelloScalaList {

    public static void main (String[] args) {
        List xs = list(1,2,3);
        System.out.println(xs);
    }

    public static <T> List<T> list(T ... ts) {
        List<T> result = List$.MODULE$.empty();
        for(int i = ts.length; i > 0; i--) {
            result = new $colon$colon(ts[i - 1], result);
        }
        return result;
    }
}

[更新]

由于这个问题,我开始了一个名为“Scava”的小项目,以支持从 Java 到 Scala 的调用:http ://code.google.com/p/scava-org/

于 2010-12-24T09:34:30.760 回答
6

这种语法的问题:

List xs = List(1, 2, 3);

是它是Scala,而不是Java。当你在 Scala 中实例化一个像这样的对象时,语法糖会调用类的伴生对象的 apply() 方法。您必须在 Java 中手动执行此操作。

而且您实际上并没有创建 scala.collection.immutable.List (这是抽象的):

scala> val list = List(1,2,3)                      
list: List[Int] = List(1, 2, 3)
scala> list.getClass                               
res12: java.lang.Class[_] = class scala.collection.immutable.$colon$colon

从 Java 调用 Scala 并不像从 Scala 调用 Java 那样有趣。我认为您可以更轻松地将 Scala 列表转换为 Java 集合。在 Java 中使用任何 Scala List 高阶函数都会很困难,如果没有这些函数,无论如何你几乎都有一个 Java 集合。

于 2010-12-24T08:06:52.480 回答