简体   繁体   English

Scala:反射 API 调用具有相同名称的两个方法之一

[英]Scala: Reflection APIs to call one of the two methods with the same name

I am trying to use Scala Reflection APIs to call one of the two methods with the same name.我正在尝试使用 Scala 反射 API 来调用具有相同名称的两种方法之一。 Only difference is that one of them takes an argument but the other one doesn't.唯一的区别是其中一个接受了参数,而另一个不接受。 I want to call the one that doesn't take any arguments.我想调用不带任何参数的那个。 I am trying something like this:我正在尝试这样的事情:

  val ru = scala.reflect.runtime.universe
  val rm = ru.runtimeMirror(getClass.getClassLoader)
  val instanceMirror = rm.reflect(myInstance)
  val methodSymbol = instanceMirror.symbol.typeSignature.member(ru.TermName("getXyzMethod")).asTerm.alternatives

  if (methodSymbol != null && methodSymbol.nonEmpty) {
    try {
      val method = instanceMirror.reflectMethod(methodSymbol.head.asMethod)
      val value = method()
      }
    } catch {
      case e: java.lang.IndexOutOfBoundsException =>
        val method = instanceMirror.reflectMethod(methodSymbol.last.asMethod)
        val value = method()

      case e: Exception =>
    }
  }

This works but as you can see this is a bit ugly.这有效,但正如您所见,这有点难看。 The reason for doing it this way is that the 'methodSymbol' is a list in which the method I want is sometimes in the 'head' position & sometimes in the 'last' position.这样做的原因是“methodSymbol”是一个列表,其中我想要的方法有时位于“头部”位置,有时位于“最后”位置。

How do I use Scala Reflection APIs to get only the method that I want which has no arguments?如何使用 Scala 反射 API 仅获取我想要的没有参数的方法?

You can do something like this:你可以这样做:

  val ru: JavaUniverse = scala.reflect.runtime.universe
  val rm: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
  val instanceMirror: ru.InstanceMirror = rm.reflect(myInstance)

  val methodSymbol: Seq[ru.Symbol] =
    instanceMirror.symbol.typeSignature.member(ru.TermName("getXyzMethod")).asTerm.alternatives
  val maybeMethods: Try[ru.MethodSymbol] = Try(methodSymbol.map(_.asMethod).filter(_.paramLists.flatten.isEmpty).head)


  val result: ru.MethodMirror = maybeMethods match {
    case Failure(exception) => //do something with it
      throw new Exception(exception)
    case Success(value) => instanceMirror.reflectMethod(value)
  }

  println(result)

This will always return the method with no parameters.这将始终返回没有参数的方法。

Being like this:像这样:

def getXyzMethod() = ???

or或者

def getXyzMethod = ???

Adjust the size of the sequence if that method as more parameters, so if the method you want has exactly 1 parameter:如果该方法作为更多参数,则调整序列的大小,因此如果您想要的方法正好有 1 个参数:

val maybeMethods: Try[ru.MethodSymbol] = Try(methodSymbol.map(_.asMethod).filter(_.paramLists.flatten.size==1).head)

And so on, hope this helps.等等,希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM