In Scala, is it possible to instantiate an object of generic type T?

Viewed 864

In Scala, even if the solution is not elegant, is it possible to instantiate/create a new object of a generic type T? Is it possible to achieve this using reflection?

For example, I am interested in something like the following:

    case class Person(name: String, age: Int)

Let's say I wanted to do the following to create an object of type Person:

    def createObject[T](fieldValues: Seq[Any]): T = {
        ... T(fieldValues)
    }

    val person = createObject[Person](Seq("Bob", 20))
2 Answers

No, it is not possible. T is a parameter. You do not know anything about it. You do not even know if it can be instantiated at all. It might be a trait or an abstract class or a singleton type or a compound type.

That is the whole point of parametric polymorphism. To write code that does not need to know anything about the types it is dealing with.

Just as an example, it is perfectly legal to call your method like this:

val goodLuck = createObject[Nothing](Seq(1, 2))

Well, Nothing is literally defined as "the type which cannot have an instance". How are you going to instantiate this?

Technically speaking it's possible using reflection. You could for example catch runtime class of type T using ClassTag then find proper constructor and create instance:

def createObject[T](fieldValues: Seq[Any])(implicit ct: ClassTag[T]): Option[T] = {
   //we lookup for matching constructor using arguments count, you might also consider checking types
   ct.runtimeClass.getConstructors.find(_.getParameterCount == fieldValues.size) 
   .flatMap {constructor =>
        Try(constructor.newInstance(fieldValues: _*).asInstanceOf[T]).toOption
    }
}

createObject[Person](Seq("Bob", 20)) //Some(Person("Bob", 20))
createObject[Person](Seq(20, 10)) //None

In case there's no constructor matching parameters, that function fails returning None.

It should work, but it'd be best if you can avoid this approach because you lose all type safety.

Related