Как получить доступ к экземпляру объекта Scala, если у него полное имя? - PullRequest
0 голосов
/ 28 августа 2018

Итак, я определил объект 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 голосов
/ 28 августа 2018

Вот решение, использующее 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...