java - 如何获取非 case 类的构造函数参数的默认值?

标签 java scala reflection

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反射......

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

例如,我们有一个 case 和一个非 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

关于java - 如何获取非 case 类的构造函数参数的默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54910494/

相关文章:

java - 动态获取当前行号

java - 使用 AES 解密文件时密码 doFinal 填充 block 损坏

scala - 如何删除这个额外的类型参数?

scala - 为什么即使在未使用的情况下,我也会在 Heroku 上收到内存配额超出错误? (play2/scala)

scala - 如何使用 Scala 将字符串转换为 ASCII

java - 在 Java 中通过类型转换分配属性值

java - SpringIntegration Poller 复制文件

java - BufferedImage 颜色 channel 蒙版

java - 从 VB.Net 执行 Java 类

c# - 如何初始化具有构造函数的动态类