我正在学习Scala,并且好奇是否有可能:
我想在scala中实现自定义lucene查询解析器,并且能够让其他人从java应用程序访问它。
答案 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集合对象(如List
和Vector
)转换为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类,可以访问方法,字段(即使它们是静态的)等等。