我可以使用实现 Java 接口的 Scala 类吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2349241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I use a scala class which implements a java interface from Java?
提问by tommy chheng
I'm learning Scala and was curious if it would be possible to:
我正在学习 Scala 并且很好奇是否有可能:
- Create an object which implements a Java interface in Scala
- Compile the object into a class file and jar it
- Use the object from Java
- 创建一个在 Scala 中实现 Java 接口的对象
- 将对象编译成类文件并进行jar
- 使用 Java 中的对象
I want to implement a custom lucene query parser in scala and be able to let others access it from a java application.
我想在 Scala 中实现一个自定义的 lucene 查询解析器,并能够让其他人从 Java 应用程序访问它。
回答by Daniel Spiewak
I'm assuming that by "object" you actually mean "class". In any case, the answer is yes, you can do this. You will need to take advantage of the Scala/Java joint compiler if you want this all in the same project. For example:
我假设“对象”实际上是指“类”。无论如何,答案是肯定的,您可以这样做。如果您希望在同一个项目中实现这一切,您将需要利用 Scala/Java 联合编译器。例如:
public interface Parser {
public TokenIterator parse(InputStream is);
}
Then in Scala:
然后在 Scala 中:
class ParserImpl extends Parser {
def parse(is: InputStream) = ...
}
Finally, in Java again:
最后,再次在 Java 中:
public class Consumer {
public static void main(String[] args) {
Parser p = new ParserImpl(); // just like a Java class!
...
}
}
If all of these source files are in the same project, then you will want to compile them using the following invocation of commands:
如果所有这些源文件都在同一个项目中,那么您将需要使用以下命令调用来编译它们:
$ scalac *.scala *.java
$ javac -classpath . *.java
The first command invokes the Scala/Java joint compiler, which will compile the Scala sources and just enough of the Java sources to satisfy any dependencies. The second command invokes the Java compiler with the recently-compiled Scala classes on the classpath.
第一个命令调用 Scala/Java 联合编译器,它将编译 Scala 源代码和足够满足任何依赖项的 Java 源代码。第二个命令使用类路径上最近编译的 Scala 类调用 Java 编译器。
回答by huynhjl
I have implemented a custom org.apache.solr.handler.RequestHandlerBaseand custom org.apache.solr.request.QueryResponseWriterin Scala 2.8 with Java 1.6.0 and Solr 1.4.0. I am not sure of the Lucene version Solr 1.4.0 is using but I would assume a fairly recent one. Anyway, I packaged the class files generated by Scala in a jar and Solr was able to load it just fine. So what you are trying to do is possible.
我已经使用 Java 1.6.0 和 Solr 1.4.0 在 Scala 2.8 中实现了自定义org.apache.solr.handler.RequestHandlerBase和自定义org.apache.solr.request.QueryResponseWriter。我不确定 Solr 1.4.0 正在使用的 Lucene 版本,但我会假设一个相当新的版本。无论如何,我将 Scala 生成的类文件打包在一个 jar 中,Solr 能够很好地加载它。所以你正在尝试做的事情是可能的。
I would say the main thing to overcome is to convert from Java collection objects like Listand Vectorto Scala collection objects and vice versa. scala.collection.JavaConversionsin Scala 2.8.0 will probably be your friend.
我会说要克服的主要问题是从 Java 集合对象(如List和 )转换Vector为 Scala 集合对象,反之亦然。scala.collection.JavaConversions在 Scala 2.8.0 中可能会是你的朋友。
One other thing, if you need to override a method like getBooleanQuery, you may need to add [_]to make Scala compile (code not tested - but since it took me a while to figure that kind of stuff out when I started Scala, I thought I'd share):
另一件事,如果您需要覆盖像getBooleanQuery这样的方法,您可能需要添加[_]以使 Scala 编译(代码未经测试 - 但由于我在启动 Scala 时花了一段时间才弄清楚那种东西,我想我'd 分享):
override def getBooleanQuery(clauses: java.util.List[_]): Query = { ... }
Edit:: One more thing about the joint compilation. Daniel's information on how to joint compile is useful. You may not immediately need it though, as very likely, you just need to have scalacknow the path to the Lucene jar files, then package your class in a new jar, and have your jar file used at runtime in the deployed environment.
编辑::关于联合编译的另一件事。Daniel 关于如何联合编译的信息很有用。不过,您可能不会立即需要它,因为很有可能,您只需要scalac知道 Lucene jar 文件的路径,然后将您的类打包到一个新 jar 中,并在部署环境中在运行时使用您的 jar 文件。
回答by Esko Luontola
Yes it's possible. Some of the Scala features (such as singleton objects) will compile to code which is hard to use from Java, but using Scala classes through a Java interface is an easy way to write compatible code.
是的,这是可能的。一些 Scala 功能(例如单例对象)将编译为难以从 Java 使用的代码,但通过 Java 接口使用 Scala 类是编写兼容代码的一种简单方法。
Some questions about Java interoperability are answered at http://www.scala-lang.org/faq/4and in the book Programming in Scala. Quoted from that FAQ:
有关 Java 互操作性的一些问题在http://www.scala-lang.org/faq/4和Programming in Scala一书中得到了解答。引自该常见问题解答:
Can I use existing Java code from Scala?
Accessing Java classes from Scala code is no problem at all. Using a Scala class from Java can get tricky, in particular if your Scala class uses advanced features like generics, polymorphic methods, or abstract types. Since Java doesn't have such language features, you have to know something about the encoding scheme of Scala classes. Otherwise, there should be no problems.
Do I need to convert Java data structures to Scala, and vice versa?
You do not have to convert Java data structures at all for using them in Scala. You can use them "as is". For instance, Scala classes can subclass Java classes, you can instantiate Java classes in Scala, you can access methods, fields (even if they are static), etc.
我可以使用来自 Scala 的现有 Java 代码吗?
从 Scala 代码访问 Java 类完全没有问题。使用来自 Java 的 Scala 类可能会很棘手,特别是如果您的 Scala 类使用泛型、多态方法或抽象类型等高级特性。由于Java 没有这样的语言特性,因此您必须了解Scala 类的编码方案。否则,应该没有问题。
我是否需要将 Java 数据结构转换为 Scala,反之亦然?
您根本不必转换 Java 数据结构即可在 Scala 中使用它们。您可以“按原样”使用它们。例如,Scala 类可以继承 Java 类,您可以在 Scala 中实例化 Java 类,您可以访问方法、字段(即使它们是静态的)等。

