如何在Java中使用Scala隐式类

时间:2016-04-08 10:58:29

标签: java scala cloudera-cdh

我有一个来自RecordService API的Scala Implicit类,我想在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中,导入功能略有不同,而且工作正常。

4 个答案:

答案 0 :(得分:7)

这是包对象

中隐式类的简单定义
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");

答案 1 :(得分:1)

package object spark编译为包package中的班级spark。隐式类RecordServiceContext将被编译为RecordServiceContext中的静态方法package(即scala的隐式def)和类package$RecordServiceContext。< / p>

所以下面的代码应该这样做:

import com.cloudera.recordservice.spark.*;

//some code

RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile);

//some code

package可能是一个保留关键字,据我所知,Java无法逃避它们。因此,您必须做一些反思来调用RecordServiceContext方法。

答案 2 :(得分:0)

 SparkContext ctx = ...
 RecordServiceContext rsct = new RecordServiceContext(ctx)
 recordServiceTextFile("/your_path")

答案 3 :(得分:0)

这应该这样做。

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构造。

另外,值得深思的是#34;定义一个可以在包对象内部访问的东西真的有意义吗? &#34;