如何使用反射调用Scala Object方法?

san*_*jib 33 reflection scala object

说,我有以下几点:

trait SomeTrait {
  def someMethod: String;
}

object SomeObject extends SomeTrait {
  def someMethod = "something";
}
Run Code Online (Sandbox Code Playgroud)

我想使用反射调用"someMethod",因为我将对象名称作为String.就像是:

val objectName = "SomeObject"  
val someTrait:SomeTrait = ???.asInstanceOf[SomeTrait]  
someTrait.someMethod
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

谢谢

Tho*_*ung 21

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
Run Code Online (Sandbox Code Playgroud)

  • 它如何在 2.10 中通过反射进行转换? (3认同)
  • 你需要清单吗?我发现`Class.forName(name +"$").getField("MODULE $").get(null)`就足够了.静态字段允许这样做. (2认同)

小智 15

从scala 2.10开始,我们可以使用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
Run Code Online (Sandbox Code Playgroud)


Arj*_*ijl 13

对于类,可以使用标准的java反射classOf方法轻松完成.对于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
Run Code Online (Sandbox Code Playgroud)

  • 我认为如果你创建一个新的实例,它确实打破了伴侣(单例)对象的客户期望. (2认同)