通过反射实例化具有默认参数的案例类 [英] Instantiating a case class with default args via reflection

查看:34
本文介绍了通过反射实例化具有默认参数的案例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够通过反射实例化各种 case 类,既要弄清楚构造函数的参数类型,又要使用所有默认参数调用构造函数.

I need to be able to instantiate various case classes through reflection, both by figuring out the argument types of the constructor, as well as invoking the constructor with all default arguments.

我已经走到这一步了:

import reflect.runtime.{universe => ru}
val m = ru.runtimeMirror(getClass.getClassLoader)

case class Bar(i: Int = 33)

val tpe      = ru.typeOf[Bar]
val classBar = tpe.typeSymbol.asClass
val cm       = m.reflectClass(classBar)
val ctor     = tpe.declaration(ru.nme.CONSTRUCTOR).asMethod
val ctorm    = cm.reflectConstructor(ctor)

// figuring out arg types
val arg1 = ctor.paramss.head.head
arg1.typeSignature =:= ru.typeOf[Int] // true
// etc.

// instantiating with given args
val p = ctorm(33)

现在缺少的部分:

val p2 = ctorm()  // IllegalArgumentException: wrong number of arguments

那么如何使用 Bar 的默认参数创建 p2,即没有反射的 Bar() 是什么.

So how can I create p2 with the default arguments of Bar, i.e. what would be Bar() without reflection.

推荐答案

未最小化...并且不支持...

Not minimized... and not endorsing...

scala> import scala.reflect.runtime.universe
import scala.reflect.runtime.universe

scala> import scala.reflect.internal.{ Definitions, SymbolTable, StdNames }
import scala.reflect.internal.{Definitions, SymbolTable, StdNames}

scala> val ds = universe.asInstanceOf[Definitions with SymbolTable with StdNames]
ds: scala.reflect.internal.Definitions with scala.reflect.internal.SymbolTable with scala.reflect.internal.StdNames = scala.reflect.runtime.JavaUniverse@52a16a10

scala> val n = ds.newTermName("foo")
n: ds.TermName = foo

scala> ds.nme.defaultGetterName(n,1)
res1: ds.TermName = foo$default$1

这篇关于通过反射实例化具有默认参数的案例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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