Scala Reflection Instantiating class 与此 spark 模式结构中的嵌入式外部库有关的问题

Scala Reflection Instantiating class issues with embded external library in this spark schema structs

我看到很多关于 Scala 反射库的网站,但其中 none 有一个直接的答案,即在运行时实例化 class 的对象。 例如,我有以下代码:

trait HydraTargetTable {
 val inputTables = Seq.empty[Int]
 val tableType: String
 val tableName: String
 val schema: StructType
 def className: String = this.getClass.toString
}

trait HydraIntermediateTable extends HydraTargetTable {
  val tableType = "Intermediate"

  def build(textRDD: RDD[String]): DataFrame = {
    DataframeUtils.safeParseFromSchema(textRDD, schema)
  }
}
class Table1 extends HydraIntermediateTable {
  override val inputTables: Seq[Int] = Seq(1, 2)
  override val tableName: String = ""
 override val schema: StructType = new StructType()
}

在运行时,我希望能够在给定 class 名称作为字符串值的情况下实例化 Table1 的对象。这是我的反射代码。

object ReflectionTestApp {

  def tableBuilder(name: String): Intermediate = {
    Class.forName("hearsay.hydra.dataflow.api." + name).newInstance()
     .asInstanceOf[Intermediate]
  }

  def hydraTableBuilder(name: String): HydraTargetTable = {
    val action = Class
     .forName("hearsay.hydra.dataflow.api." + name).newInstance()
    action.asInstanceOf[HydraTargetTable]
  }

  def main(args: Array[String]): Unit = {
   hydraTableBuilder("Table1").inputTables.foreach(println)
  }

 }

下面是如何为 Object/Class 实现反射。

package reflection

trait Table {
  val id: Int
}

class ActivityTable extends Table {
  val id = 10
}

object ActivityTable2 extends Table {
  val id = 10
}

object Reflection extends App {

  val obj = activityTableBuilder("ActivityTable")
  println(obj.id) //output 10

  val obj2 = objectBuilder("ActivityTable2$")
  println(obj2.id) //output 10

  /*
  class reflection
   */
  def activityTableBuilder(name: String): Table = {
    val action = Class.forName("reflection." + name).newInstance()
    action.asInstanceOf[Table]
  }

  /*
  object reflection
   */
  def objectBuilder(name: String): Table = {
    val action = Class.forName("reflection." + name)
    action.getField("MODULE$").get(classOf[Table]).asInstanceOf[Table]
  }
}