2010-02-27 139 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文件。