如何在 Scala 中使用没有参数的构造函数参数创建 Case Class 的实例?

mgo*_*nto 7 reflection macros scala case-class scala-macros

我正在制作一个通过反射字段值设置的 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
Run Code Online (Sandbox Code Playgroud)

jce*_*ern 5

如果您正在寻找一种方法来实例化不带参数的对象,则可以执行与示例中相同的操作,只要您的反射设置器可以处理设置不可变的值即可。

您将提供一个备用构造函数,如下所示:

case class Person(name : String, age : Int) {
    def this() = this("", 0)
}
Run Code Online (Sandbox Code Playgroud)

请注意,案例类不会生成零参数伴随对象,因此您需要将其实例化为:new Person()classOf[Person].newInstance()。然而,这应该是您想要做的。

应该给你类似的输出:

scala> case class Person(name : String, age : Int) {
     |         def this() = this("", 0)
     |     }
defined class Person

scala> classOf[Person].newInstance()
res3: Person = Person(,0)
Run Code Online (Sandbox Code Playgroud)