如何获取非大小写类的构造函数参数的默认值? [英] How can I obtain the default value of a constructor parameter for a non-case class?

查看:48
本文介绍了如何获取非大小写类的构造函数参数的默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Person(name: String, age: Int, numThings: Option[Int] = Some(15))

我可以使用 Scala 反射来获取这样的案例类的默认值:

I can use Scala reflection to obtain defaults on a case class like this:

   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
   }

这会获取生成的伴生对象中的方法,该方法在调用时会显示默认值.遗憾的是,非案例类似乎没有这种功能.

This obtains the method in the generated companion object that, when called, coughs up the default value. Sadly, a non-case class doesn't appear to have this facility.

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

How can I obtain the default value for Person.numThings in the example above using either Scala or Java reflection?

推荐答案

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

I think that it should be much easier to retrieve these default values through Java reflection, instead of this over-complicated Scala's reflect...

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

When compiled into a .class file, default parameter values are translated into static methods with specific suffixes in names. These values can be retrieved by invoking the respective method on the class reference.

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

So, for example, we have both a case and a non-case classes:

class Person(name: String, age: Int, numThings: Option[Int] = Some(15))

case class Item(id: Long, other: String = "unknown")

首先,我们需要确定要检索默认值的参数的序数索引.我不知道你的用例,所以假设你知道或计算过它们.Person3Item2.是的,它们不是基于 0.

First we need to determine the ordinal indices of the params to retrieve defaults for. I do not know your use case, so let's suppose you know or calculated them. They will be 3 for Person and 2 for Item. Yes, they are not 0-based.

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

And this very short method retrieves the values:

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

这篇关于如何获取非大小写类的构造函数参数的默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆