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

How to access a Scala object instance given it's full qualified name?

所以我使用以下代码定义了一个 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 方法一部分的代码应该是什么?

这是一个使用 Java 反射 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 的评论非常相似,有两个细微差别:请注意 class 名称后附加的 '$',以及 .get(clazz) 而不仅仅是 .get() (没有 clazz,它会抛出 java.lang.NoSuchFieldException: MODULE$)。

保存到文件 f.scala 并使用

编译和调用时
scalac f.scala && scala Demo

它打印:

impl 2