如何通过反射调用伴生对象的方法? [英] How to invoke method on companion object via reflection?

查看:60
本文介绍了如何通过反射调用伴生对象的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类名和一个方法,其类型参数我知道,我想通过反射调用这个方法.

I have a class name and a method whose type parameters I know, and I'd like to invoke this method via reflection.

在java中我会做类似的事情:

In java I'd do something like:

Class.forName("foo").getMethod("name", ... type args...).invoke(null, ..args)

但是在 Scala 中,每当我尝试调用时,都会收到空引用错误.

However in Scala, whenever I try and invoke I get a null ref error.

我使用的是 Scala 2.10.4

I'm using scala 2.10.4

--编辑

我试过了:

$ scala
Welcome to Scala version 2.10.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo { def bar(x: Int) = x }
defined class Foo

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> val foo = new Foo
foo: Foo = Foo@2db7a79b

scala> runtimeMirror(getClass.getClassLoader).reflect(foo)
res0: reflect.runtime.universe.InstanceMirror = instance mirror for Foo@2db7a79b

scala> res0.symbol.typeSignature.member(newTermName("bar"))
res1: reflect.runtime.universe.Symbol = method bar

scala> res0.reflectMethod(res1.asMethodSymbol)(42)
<console>:15: error: value asMethodSymbol is not a member of reflect.runtime.universe.Symbol
              res0.reflectMethod(res1.asMethodSymbol)(42)
                                      ^

Dynamic"为例使用新的 Scala 反射 API 进行方法调用 似乎不再起作用

这是我正在尝试做的测试:

Here is a test of what I am trying to do:

object Test{
  def run(): Boolean = true
}

class InvokeTests extends FlatSpec with Matchers {
  "invoke" should "do" in {
    import scala.reflect.runtime.universe._

    val mirror = runtimeMirror(this.getClass.getClassLoader)

    val moduleSymbol = mirror.moduleSymbol(Class.forName(Test.getClass.getName))

    val reflected = mirror.reflect(moduleSymbol)

    val methodName = reflected.symbol.typeSignature.member(newTermName("run"))

    reflected.reflectMethod(methodName.asMethod)() shouldBe true
  }
}

推荐答案

参考 scala 文档反射概述

// get runtime universe
val ru = scala.reflect.runtime.universe

// get runtime mirror
val rm = ru.runtimeMirror(getClass.getClassLoader)

// define class and companion object
class Boo{def hey(x: Int) = x}; object Boo{def hi(x: Int) = x*x}

// get instance mirror for companion object Boo
val instanceMirror = rm.reflect(Boo)

// get method symbol for the "hi" method in companion object
val methodSymbolHi = ru.typeOf[Boo.type].decl(ru.TermName("hi")).asMethod

// get method mirror for "hi" method
val methodHi = instanceMirror.reflectMethod(methodSymbolHi)

// invoke the method "hi"
methodHi(4)  // 16

这篇关于如何通过反射调用伴生对象的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆