如何在 Java 中使用 Scala 隐式类
Posted
技术标签:
【中文标题】如何在 Java 中使用 Scala 隐式类【英文标题】:How to use Scala implicit class in Java 【发布时间】:2016-04-08 10:58:28 【问题描述】:我有一个来自 RecordService API 的 Scala 隐式类,我想在 Java 文件中使用它。
package object spark
implicit class RecordServiceContext(ctx: SparkContext)
def recordServiceTextFile(path: String) : RDD[String] =
new RecordServiceRDD(ctx).setPath(path)
.map(v => v(0).asInstanceOf[Text].toString)
现在我正在尝试使用以下导入将其导入到 Java 文件中。
import com.cloudera.recordservice.spark.*;
但我无法使用 sparkContext 中的 recordServiceTextFile("path")。
在 Scala 中,导入和它的工作方式略有不同。
【问题讨论】:
我没有看到隐式类。 在 Java 代码中导入 Scala 代码在我看来并不是一件小事。它需要对 javac 内部结构有所了解。问题也不清楚。你能在这个问题上更清楚一点吗?问题越“完整”,答案就越好。 @Ramesh 不客气,但那不是我。 【参考方案1】:这是包对象中隐式类的简单定义
package object spark
implicit class Ext(param: Int)
def a = param + 1
下面是如何从 java 中使用它
public class Test
public static void main(String[] args)
spark.package$.MODULE$.Ext(123).a();
所以您基本上可以使用RecordServiceContext
作为包装您的SparkContext
并添加一个您可以调用的额外方法的方法。那是对隐式类的优化。
应该是这样的:
SparkContext c = ???
RDD<String> rdd = com.cloudera.recordservice.spark.package$.MODULE$.RecordServiceContext(c)
.recordServiceTextFile("asdf");
【讨论】:
【参考方案2】:package object spark
编译为包spark
中的类package
。隐式类 RecordServiceContext
将被编译为 package
中的静态方法 RecordServiceContext
(这是 scala 的隐式定义)和类 package$RecordServiceContext
。
所以下面的代码应该做到这一点:
import com.cloudera.recordservice.spark.*;
//some code
RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile);
//some code
但是package
可能是一个保留关键字,据我所知,Java 无法转义它们。所以你必须做一些反射来调用RecordServiceContext
方法。
【讨论】:
【参考方案3】: SparkContext ctx = ...
RecordServiceContext rsct = new RecordServiceContext(ctx)
recordServiceTextFile("/your_path")
【讨论】:
【参考方案4】:应该这样做。
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
不过我更改了签名。
我的 Scala 类看起来像这样,
object spark
implicit class RecordServiceContext(ctx: String)
def recordServiceTextFile(path: String) : String =
"test"
我的java类是这样的,
public class TestScalaCall
public static void main(String args[])
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
编辑---
因此,快速浏览一下 Scala 变更请求会告诉我们this。
他们实际上正在努力使在package object
下定义的类的行为与在常规package
中定义它的方式相同。但这是针对尚未发布的2.12
。
所以他们给出的建议是只保留绝对必要的类/对象,这些类/对象不需要在包对象内进行任何外部交互。否则,请将它们放在常规包装中。
所以现在你不需要使用package object
构造。
另外,值得思考的一点是“在包对象内部定义可从外部访问的东西真的有意义吗?”
【讨论】:
你的隐式类在object spark
之前缺少package
,这是我面临的主要问题......
我在答案中添加了解释。这是 scala 团队正在做的事情。以上是关于如何在 Java 中使用 Scala 隐式类的主要内容,如果未能解决你的问题,请参考以下文章