Scala将字符串反映到单例对象

时间:2017-03-08 00:22:37

标签: scala reflection scala-reflect scala-meta

我正在寻找一种方法将Scala单例对象转换为以字符串形式(例如:package1.Main)转换为Main的实际实例,以便我可以在其上调用方法。

问题示例:

package x {
  object Main extends App {
    val objectPath: String = io.StdIn.readLine("Give an object: ") // user enters: x.B

    // how to convert the objectPath (String) to a variable that references singleton B?
    val b1: A = magicallyConvert1(objectPath)
    b1.hi()

    val b2: B.type = magicallyConvert2(objectPath)
    b2.extra()
  }

  trait A {
    def hi() = {}
  }

  object B extends A {
    def extra() = {}
  }
}

如何实现magicallyConvert1和magicallyConvert2功能?

2 个答案:

答案 0 :(得分:1)

对于普通班级,可以使用以下内容完成:

val b: A = Class.forName("x.B").newInstance().asInstanceOf[A]

但是我使用Java反射找到了单身人士的解决方案:

单例可以在Java中以名称访问: package.SingletonName $ .MODULE $ 所以你必须附加" $。MODULE $",这是一个静态字段。 所以我们可以使用标准的Java反射来获得它。

所以解决方案是:

def magicallyConvert1(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: A = field.get(null).asInstanceOf[A]
  b
}

def magicallyConvert2(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: B.type = field.get(null).asInstanceOf[B.type]
  b
}

但是仍然可以看到使用Scala-Reflect和Scala-Meta的解决方案。

答案 1 :(得分:0)

看看scalameta http://scalameta.org它能做你想做的事情还有更多