我可以直接在Java中使用scala List吗?

我可以在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 List,编译器抱怨

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

我不知道这是什么意思。


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

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

  1. 直接在java中使用scala List

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

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

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

一个小的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  List list(T ... ts) { List 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/

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

但您可以使用以下代码:

  public static  scala.collection.immutable.List scalaList(List javaList) { return scala.collection.JavaConversions.asScalaIterable(javaList).toList(); } 

这种语法的问题:

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 Collection。 在Java中使用任何Scala List高阶函数都很困难,如果没有这些函数,你几乎都有Java Collection。