![](/img/trans.png)
[英]Invoke java.lang.reflect.Method in Scala with Object array
[英]Invoke a method on a generic type with scala and reflect package
我的問題是基於我在以下頁面上進行的搜索(但是我仍然對scala陌生,無法成功完成自己想做的事情):
我的代碼的目的是從通用類型而不是已知類型的實例調用方法。
以下說明了這個想法:
class A {
def process = {
(1 to 1000).foreach(x => x + 10)
}
}
def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
def perf[T: ru.TypeTag](t: T, sMethodName: String): Any = {
val m = ru.runtimeMirror(t.getClass.getClassLoader)
val myType = ru.typeTag[T].tpe
val mn = myType.declaration(ru.newTermName(sMethodName)).asMethod
val im = m.reflect(getTypeTag(t))
val toCall = im.reflectMethod(mn)
toCall()
}
val a = new A
perf(a, "process")
該代碼可以完美地編譯(在工作表上),但是在執行時提供以下堆棧:
scala.ScalaReflectionException: expected a member of class TypeTagImpl, you provided method A$A11.A$A11.A.process
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$ErrorNotMember(test-log4j.sc:126)
at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf$1.apply(test-log4j.sc:221)
at scala.reflect.runtime.JavaMirrors$JavaMirror.ensuringNotFree(test-log4j.sc:210)
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf(test-log4j.sc:220)
at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:257)
at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:239)
at #worksheet#.perf(test-log4j.sc:20)
at #worksheet#.get$$instance$$res0(test-log4j.sc:28)
at #worksheet#.#worksheet#(test-log4j.sc:138)
關於如何糾正這個想法?
非常感謝所有人
為了反映特定對象,您必須將其傳遞給Mirror.reflect(obj: T)
,並且出於某種原因要傳遞其typeTag。 要解決此問題,您必須修改perf
簽名以生成ClassTag
和TypeTag
,然后將t
直接傳遞給reflect
,如下所示:
class A {
def process = {
(1 to 1000).foreach(x => x + 10)
println("ok!")
}
}
def perf[T : ClassTag : ru.TypeTag](t: T, sMethodName: String): Any = {
// ^ modified here
val m = ru.runtimeMirror(t.getClass.getClassLoader)
val myType = ru.typeTag[T].tpe
val mn = myType.decl(ru.TermName(sMethodName)).asMethod
val im = m.reflect(t)
// ^ and here
val toCall = im.reflectMethod(mn)
toCall()
}
val a = new A
perf(a, "process")
// ok!
// res0: Any = ()
(注意:我還用推薦的替代品替換了已棄用的declaration
和newTermName
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.