2010-02-27 93 views
17

我学习Scala和很好奇,如果有可能于:我可以使用从Java实现java接口的scala类吗?

  1. 创建一个实现了在斯卡拉
  2. Java接口
  3. 对象编译成类文件和JAR它
  4. 使用一个对象来自Java的对象

我想在scala中实现一个自定义lucene查询分析器,并且能够让其他人从java应用程序中访问它。

回答

28

我假设你实际上是指“阶级”。无论如何,答案是肯定的,你可以这样做。如果你想把这一切都放在同一个项目中,你需要利用Scala/Java联合编译器。例如:

public interface Parser { 
    public TokenIterator parse(InputStream is); 
} 

然后在斯卡拉:

class ParserImpl extends Parser { 
    def parse(is: InputStream) = ... 
} 

最后,在Java中再次:

public class Consumer { 
    public static void main(String[] args) { 
     Parser p = new ParserImpl();  // just like a Java class! 
     ... 
    } 
} 

如果所有这些源文件都在同一个项目,那么你将要使用以下命令调用它们进行编译:

$ scalac *.scala *.java 
$ javac -classpath . *.java 

第一条命令调用Scala/Java联合编译器,它将编译Scala源代码和足够的Java源代码以满足任何依赖关系。第二个命令使用类路径上最近编译的Scala类调用Java编译器。

1

是的,这是可能的。某些Scala特性(例如单例对象)将编译为难以从Java中使用的代码,但通过Java接口使用Scala类是编写兼容代码的简单方法。

有关Java互操作性的一些问题在http://www.scala-lang.org/faq/4Programming in Scala的书中得到解答。引用该FAQ:

我可以使用Scala的现有Java代码吗?

从Scala代码访问Java类完全没有问题。使用Java中的Scala类可能会非常棘手,特别是如果您的Scala类使用泛型,多态方法或抽象类型等高级功能。由于Java没有这样的语言特性,你必须知道一些关于Scala类的编码方案。否则,应该没有问题。

我是否需要将Java数据结构转换为Scala,反之亦然?

您不必转换Java数据结构就可以在Scala中使用它们。您可以“按原样”使用它们。例如,Scala类可以继承Java类,你可以在Scala中实例化的Java类,您可以通过“对象”访问方法,字段(即使它们是静态的),等等。

3

我已经在Scala 2.8中使用Java 1.6.0和Solr 1.4.0实现了自定义org.apache.solr.handler.RequestHandlerBase和自定义org.apache.solr.request.QueryResponseWriter。我不确定Solr 1.4.0正在使用的Lucene版本,但我会假设一个相当新的版本。无论如何,我将由Scala生成的类文件打包在一个jar文件中,并且Solr能够很好地加载它。所以你试图做的事情是可能的。

我想说,克服了主要的是从Java集合对象转换像ListVector Scala的集合对象,反之亦然。 Scala 2.8.0中的scala.collection.JavaConversions可能会成为你的朋友。

还有一件事,如果你需要重写像getBooleanQuery的方法,你可能需要添加[_]使斯卡拉编译(代码没有测试 - 而是因为我花了一段时间才能弄清楚这样的东西出来的时候,我开始Scala中,我想我会分享):

override def getBooleanQuery(clauses: java.util.List[_]): Query = { ... } 

编辑::关于联合编制一两件事。 Daniel关于如何联合编译的信息很有用。您可能不会立即需要它,因为很可能您只需要知道Lucene jar文件的路径,然后将您的类打包到新的jar文件中,然后在运行时在部署的环境中使用您的jar文件。