我正在寻找一种方法将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功能?
答案 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它能做你想做的事情还有更多