Вот решение, использующее 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()
}
}
Это очень похоже на комментарий Димы выше, с двумя незначительными отличиями: обратите внимание на '$'
, добавляемое к имени класса, а также .get(clazz)
вместо просто .get()
(без clazz
, выдает java.lang.NoSuchFieldException: MODULE$
).
При сохранении в файл f.scala
, компиляции и вызове с использованием
scalac f.scala && scala Demo
печатает:
impl 2