首页 > 解决方案 > 如何在Scala中基于方法签名来反映构造方法

问题描述

class Test(a: String, b: Array[String], c: Array[String]){
  def this(b: Array[String], c: Array[String]) {
    this("1", b, c)
  }

  def this() = {
    this(null, null, null)
  }
}

我有一个像上面一样的类 Test ,我想使用 scala 反射来调用其中一个

我尝试使用以下代码

import scala.reflect.runtime.{universe => ru}
val clsTest = ru.typeOf[Test].typeSymbol.asClass
val cm = m.reflectClass(clsTest)
val ctor =  ru.typeOf[Test].decl(ru.termNames.CONSTRUCTOR).asTerm.alternatives.map(_.asMethod)

但我不知道如何根据方法签名选择方法。是否有任何方法可以根据类型签名选择方法,如 java 反射代码?谢谢!

我已经阅读了关于反射的 scala 文档,但它并没有解决我的问题。它只有一种构造方法。斯卡拉反映文档

标签: scalareflection

解决方案


// the method as List(list(a,b,c))
// and this is PrimaryConstructor
class Test(a: String, b: Array[String], c: Array[String]) {
  // the method as List(list(b,c))
  def this(b: Array[String], c: Array[String]) {
    this("1", b, c)
  }

  // the method as List(list())
  def this() = {
    this(null, null, null)
  }

  // the method as List(list(a),list(b,c)
  def this(a:String )(b:String,c:String ){
    this(null,null,null)
  }
}

val constructor = typeOf[Test].members
  // filter all constructor
  .filter(e => e.isConstructor).map(e => e.asMethod)
  // find which are you want 
  // edit 1
  .find( e =>{
    val methodParamsType =  e.paramLists.head.map(e =>e.typeSignature)
    // what params  type are you 
    val expectParamsType = List(typeOf[Array[String]],typeOf[Array[String]])

    methodParamsType.length == expectParamsType.length && 
      methodParamsType.zip(expectParamsType).forall{case (l,r)=>l =:= r }
  })
  //   or
  //  .find(e=>e.isPrimaryConstructor)
  //  .find(e=>e.paramLists.head.length == 2)
  .get

推荐阅读