gpt4 book ai didi

scala - 如何通过反射调用伴生对象的方法?

转载 作者:行者123 更新时间:2023-12-03 09:32:08 25 4
gpt4 key购买 nike

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

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

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

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

我正在使用 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" method invocation with new Scala reflection API 的示例这似乎不再起作用

这是我正在尝试做的测试:
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 doc reflection overview

// 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

关于scala - 如何通过反射调用伴生对象的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39134803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com