给定全限定名称,如何访问Scala对象实例?

时间:2018-08-28 09:48:33

标签: scala reflection singleton companion-object

因此,我已使用以下代码定义了Scala对象:

trait SomeTrait {
  def someMethod(): Unit
}

package somepackage1 {
  object Impl1 extends SomeTrait {
    def someMethod(): Unit = { }
  }
  object Impl2 extends SomeTrait {
    def someMethod(): Unit = { }
  }
}

我要访问具有完全限定名称(即somepackage1.Impl2)的对象。如下所示的方法:

package object somewhereElse {
  def getImpl(qualifiedName: String): SomeTrait = {
    ???
  }
}

作为getImpl方法一部分的代码应该是什么?

1 个答案:

答案 0 :(得分:1)

这是使用Java Reflection API的解决方案(您可能想使用较新的Scala Reflection API):

trait SomeTrait {
  def someMethod(): Unit
}

package somepackage1 {
  object Impl1 extends SomeTrait {
    def someMethod(): Unit = { println("impl 1") }
  }
  object Impl2 extends SomeTrait {
    def someMethod(): Unit = { println("impl 2") }
  }
}

package object somewhereElse {
  def getImpl(qualifiedName: String): SomeTrait = {
    val clazz = Class.forName(qualifiedName + "$")
    clazz
      .getField("MODULE$")
      .get(clazz)
      .asInstanceOf[SomeTrait]
  }
}

object Demo {
  def main(args: Array[String]): Unit = {
    somewhereElse.getImpl("somepackage1.Impl2").someMethod()
  }
}

这与Dima的上述注释非常相似,但有两个小区别:请注意,在类名后附加了'$',还有.get(clazz)而不是.get()(不包括{{1 }},它会抛出clazz)。

保存到文件java.lang.NoSuchFieldException: MODULE$并使用编译和调用

f.scala

它打印:

scalac f.scala && scala Demo
相关问题