如何使用反射调用 Scala 对象方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3039822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:13:24  来源:igfitidea点击:

How do I call a Scala Object method using reflection?

reflectionscalaobject

提问by sanjib

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:

我想使用反射调用“someMethod”,因为我将对象名称作为字符串。就像是:

val objectName = "SomeObject"  
val someTrait:SomeTrait = ???.asInstanceOf[SomeTrait]  
someTrait.someMethod

or something similar.

或类似的东西。

Thanks

谢谢

回答by Thomas Jung

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

回答by Ambling

Since scala 2.10, we can use the reflection of Module:

从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

回答by Arjan Blokzijl

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:

对于类,这可以使用标准的 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