如何在Scala中使用没有参数的构造函数参数创建Case类的实例?
发布时间:2020-12-16 09:49:51 所属栏目:安全 来源:网络整理
导读:我正在制作一个按反射场值设置的 Scala应用程序.这很好用. 但是,为了设置字段值,我需要一个创建的实例.如果我有一个带有空构造函数的类,我可以使用classOf [Person] .getConstructors …. 但是,当我尝试使用非空构造函数的Case类时,它不起作用.我有所有字段
我正在制作一个按反射场值设置的
Scala应用程序.这很好用.
但是,为了设置字段值,我需要一个创建的实例.如果我有一个带有空构造函数的类,我可以使用classOf [Person] .getConstructors …. 但是,当我尝试使用非空构造函数的Case类时,它不起作用.我有所有字段名称及其值,以及我需要创建的对象类型.我可以用我所拥有的东西以某种方式实例化Case Class吗? 我唯一没有的是Case Class构造函数中的参数名称,或者是在没有参数的情况下创建它的方法,然后通过反射设置值. 我们来看看这个例子吧. 我有以下内容 case class Person(name : String,age : Int) class Dog(name : String) { def this() = { name = "Tony" } } class Reflector[O](obj : O) { def setValue[F](propName : String,value : F) = ... def getValue(propName : String) = ... } //This works val dog = classOf[Dog].newInstance() new Reflector(dog).setValue("name","Doggy") //This doesn't val person = classOf[Person].newInstance //Doesn't work val ctor = classOf[Person].getConstructors()(0) val ctor.newInstance(parameters) //I have the property names and values,but I don't know // which of them is for each parameter,nor I name the name of the constructor parameters 解决方法
case类应该有默认的args,这样你就可以只使用Person();在没有默认arg的情况下,为name提供null可能(或应该)命中require(name!= null).
或者,使用反射来确定哪些参数具有默认值,然后为其余参数提供空值或零. import reflect._ import scala.reflect.runtime.{ currentMirror => cm } import scala.reflect.runtime.universe._ // case class instance with default args // Persons entering this site must be 18 or older,so assume that case class Person(name: String,age: Int = 18) { require(age >= 18) } object Test extends App { // Person may have some default args,or not. // normally,must Person(name = "Guy") // we will Person(null,18) def newCase[A]()(implicit t: ClassTag[A]): A = { val claas = cm classSymbol t.runtimeClass val modul = claas.companionSymbol.asModule val im = cm reflect (cm reflectModule modul).instance defaut[A](im,"apply") } def defaut[A](im: InstanceMirror,name: String): A = { val at = newTermName(name) val ts = im.symbol.typeSignature val method = (ts member at).asMethod // either defarg or default val for type of p def valueFor(p: Symbol,i: Int): Any = { val defarg = ts member newTermName(s"$name$$default$$${i+1}") if (defarg != NoSymbol) { println(s"default $defarg") (im reflectMethod defarg.asMethod)() } else { println(s"def val for $p") p.typeSignature match { case t if t =:= typeOf[String] => null case t if t =:= typeOf[Int] => 0 case x => throw new IllegalArgumentException(x.toString) } } } val args = (for (ps <- method.paramss; p <- ps) yield p).zipWithIndex map (p => valueFor(p._1,p._2)) (im reflectMethod method)(args: _*).asInstanceOf[A] } assert(Person(name = null) == newCase[Person]()) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |