我可以使用scala类来实现Java的Java接口吗?

我正在学习Scala并且好奇是否有可能:

  1. 创建一个在Scala中实现Java接口的对象
  2. 将对象编译为类文件并将其jar
  3. 使用Java中的对象

我想在scala中实现自定义lucene查询解析器,并允许其他人从java应用程序访问它。

我假设通过“对象”你实际上意味着“阶级”。 无论如何,答案是肯定的,你可以这样做。 如果您希望在同一个项目中使用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编译器。

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

我想说要解决的主要问题是将Java集合对象(如ListVector为Scala集合对象,反之亦然。 Scala scala.collection.JavaConversions中的scala.collection.JavaConversions可能是你的朋友。

另外一件事,如果你需要覆盖像getBooleanQuery这样的方法,你可能需要添加[_]来使Scala编译(代码没有经过测试 – 但是因为我开始使用Scala时花了一些时间来计算这种东西,我以为我会分享):

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

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

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

有关Java互操作性的一些问题, 请参见http://www.scala-lang.org/faq/4和“ Scala编程 ”一书。 引用该FAQ:

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

从Scala代码访问Java类完全没问题。 使用Java中的Scala类可能会变得棘手,特别是如果您的Scala类使用generics,多态方法或抽象类型等高级function。 由于Java没有这样的语言function,因此您必须了解Scala类的编码方案。 否则,应该没有问题。

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

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