How do I call a Scala Object method using reflection?
19,870
Solution 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
Solution 2
Since scala 2.10, we can use the reflection of Module:
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
Solution 3
For classes, this can be done pretty easily using the standard java reflection classOf method. For Scala objects, it is a bit more work, but it still can be done:
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
Author by
sanjib
Updated on June 07, 2022Comments
-
sanjib almost 2 years
say, I have the following:
trait SomeTrait { def someMethod: String; } object SomeObject extends SomeTrait { def someMethod = "something"; }
I would like to call "someMethod" using reflection as I have the object name as a String. Something like:
val objectName = "SomeObject" val someTrait:SomeTrait = ???.asInstanceOf[SomeTrait] someTrait.someMethod
or something similar.
Thanks
-
Thomas Jung almost 14 yearsI think it does break the expectation of clients of a companion (singleton) object if you create new instances of it.
-
sanjib almost 14 yearsArjan - thanks. That's exactly what I was looking for. Thomas - That's true. But you could always wrap the code in an object factory and provide the singleton behavior yourself.
-
sanjib almost 14 yearsThis is even better. Thanks Thomas.
-
0__ almost 11 yearsDo you need the manifest? I found that
Class.forName(name + "$").getField("MODULE$").get(null)
is sufficient. This is allowed for static fields. -
bhericher almost 11 yearsHow does it translate in 2.10 with reflection?
-
Kevin Meredith about 10 yearsUsing Scala 2.10.2, my code threw an exception on
Class.forName(name + "$").getField("MODULE$")
-
BdEngineer over 5 years@Thomas Jung , what is the "$" here , what it refer too , sorry me new to scala.