【问题标题】:How can I obtain the default value of a constructor parameter for a non-case class?如何获取非案例类的构造函数参数的默认值?
【发布时间】:2019-02-28 05:07:38
【问题描述】:
class Person(name: String, age: Int, numThings: Option[Int] = Some(15))

我可以使用 Scala 反射来获取案例类的默认值,如下所示:

   val companionType: Type = classSymbol.companion.typeSignature
   val companionObject = currentMirror.reflectModule(classSymbol.companion.asModule).instance
   val companionMirror = currentMirror.reflect(companionObject)
   val defaultValueAccessorMirror =
   if (member.typeSignature.typeSymbol.isClass) {
     val defaultValueAccessor = companionType.member(TermName("apply$default$" + (index + 1)))
     if (defaultValueAccessor.isMethod) {
       Some(companionMirror.reflectMethod(defaultValueAccessor.asMethod))
     } else {
       None
     }
   } else {
     None
   }

这会获取生成的伴随对象中的方法,该方法在调用时会输出默认值。可悲的是,非案例类似乎没有此功能。

如何使用 Scala 或 Java 反射获取上例中 Person.numThings 的默认值?

【问题讨论】:

    标签: java scala reflection


    【解决方案1】:

    我认为通过 Java 反射来检索这些默认值应该更容易,而不是这种过于复杂的 Scala 反射......

    当编译成 .class 文件时,默认参数值被转换为名称中带有特定后缀的静态方法。可以通过调用类引用上的相应方法来检索这些值。

    因此,例如,我们有一个 case 和一个非案例类:

    class Person(name: String, age: Int, numThings: Option[Int] = Some(15))
    
    case class Item(id: Long, other: String = "unknown")
    

    首先,我们需要确定参数的序号索引以检索默认值。我不知道您的用例,所以假设您知道或计算了它们。对于Person,它们将是3,对于Item,它们将是2。是的,它们不是基于 0 的。

    这个非常短的方法检索值:

    private def extractDefaultConstructorParamValue(clazz: Class[_],
                                                    iParam: Int): Any = {
      val methodName = "$lessinit$greater$default$" + iParam
      clazz.getMethod(methodName).invoke(clazz)
    }
    

    打电话给他们

    val defParamNonCase = extractDefaultConstructorParamValue(classOf[Person], 3)
    val defParamCase = extractDefaultConstructorParamValue(classOf[Item], 2)
    
    println(defParamNonCase)
    println(defParamCase)
    

    输出

    Some(15)
    unknown
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2020-08-26
      • 2020-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多