Ответ 1
def companion[T](name : String)(implicit man: Manifest[T]) : T =
Class.forName(name + "$").getField("MODULE$").get(man.erasure).asInstanceOf[T]
val result = companion[SomeTrait]("SomeObject").someMethod
скажем, у меня есть следующее:
trait SomeTrait {
def someMethod: String;
}
object SomeObject extends SomeTrait {
def someMethod = "something";
}
Я хотел бы назвать "someMethod", используя отражение, поскольку у меня есть имя объекта как String. Что-то вроде:
val objectName = "SomeObject"
val someTrait:SomeTrait = ???.asInstanceOf[SomeTrait]
someTrait.someMethod
или что-то подобное.
Спасибо
def companion[T](name : String)(implicit man: Manifest[T]) : T =
Class.forName(name + "$").getField("MODULE$").get(man.erasure).asInstanceOf[T]
val result = companion[SomeTrait]("SomeObject").someMethod
Для классов это можно сделать довольно легко, используя стандартный метод класса java отражения. Для объектов Scala это немного больше работы, но это все еще можно сделать:
trait SomeTrait { def someMethod: String}
object SomeObject extends SomeTrait { def someMethod = "something"}
class SomeClass extends SomeTrait { def someMethod = "something"}
object Main {
def main(args:Array[String]) = {
val someClassTrait:SomeTrait = Class.forName("SomeClass").newInstance().asInstanceOf[SomeTrait]
println("calling someClassTrait: " + someClassTrait.someMethod)
val objectName = "SomeObject$"
val cons = Class.forName(objectName).getDeclaredConstructors();
cons(0).setAccessible(true);
val someObjectTrait:SomeTrait = cons(0).newInstance().asInstanceOf[SomeTrait]
println("calling someObjectTrait: " + someObjectTrait.someMethod)
}
}
//prints:
calling someClassTrait: something
calling someObjectTrait: something
Так как scala 2.10, мы можем использовать отражение модуля:
import scala.reflect.runtime.universe
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule("SomeObject")
val obj = runtimeMirror.reflectModule(module)
val someTrait:SomeTrait = obj.instance.asInstanceOf[SomeTrait]
someTrait.someMethod