Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create an instance of a Case Class with constructor arguments with no Parameters in Scala?

I'm making a Scala app that sets by reflection field values. This works OK.

However, in order to set field values I need a created instance. If I have a class with an empty constructor, I can do this easily with classOf[Person].getConstructors....

However, when I try doing this with a Case class with a non empty constructor It doesn't work. I have all of the field names and its values, as well as the Object type I need to create. Can I instance the Case Class somehow with what I've got?

The only thing I don't have is the parameter names from the Case Class constructor or a way to create this without parameter and then setting the values via reflection.

Let's go to the example.

I have the following

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
like image 735
mgonto Avatar asked Dec 11 '12 01:12

mgonto


1 Answers

If you are looking for a way to instantiate the object with no arguments, you could do the same as you did in your example, just so long as your reflection setter can handle setting the immutable vals.

You would provide an alternate constructor, as below:

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

Note that the case class will not generate a zero-arg companion object, so you will need to instantiate it as: new Person() or classOf[Person].newInstance(). However, that should be what you are looking to do.

Should give you output like:

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

scala> classOf[Person].newInstance()
res3: Person = Person(,0)
like image 63
jcern Avatar answered Sep 28 '22 01:09

jcern