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

时间:2010-02-27 22:47:38

标签: java scala interface

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

  1. 创建一个在Scala中实现Java接口的对象
  2. 将对象编译成类文件并将其jar起来
  3. 使用Java中的对象
  4. 我想在scala中实现自定义lucene查询解析器,并且能够让其他人从java应用程序访问它。

3 个答案:

答案 0 :(得分:28)

我假设“对象”你实际上是指“阶级”。无论如何,答案是肯定的,你可以这样做。如果您希望在同一个项目中使用Scala / Java联合编译器,则需要利用它。例如:

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

然后在Scala中:

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 :(得分:3)

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

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

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

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

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

答案 2 :(得分:1)

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

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

  

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

     

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

     

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

     

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