How to create case class with default parameters in Scala

Often times I have a lot of case classes in the project and I need to write some generic code that will create them using default constructor parameters.

So here is how to create case class with default parameters using Scala reflection:


import scala.reflect.runtime.universe
import scala.reflect.internal.{Definitions, SymbolTable, StdNames}

object Main {
def newInstanceWithDefaultParameters(className: String): Any = {
val runtimeMirror: universe.Mirror = universe.runtimeMirror(getClass.getClassLoader)
val ds = universe.asInstanceOf[Definitions with SymbolTable with StdNames]
val classSymbol = runtimeMirror.staticClass(className)
val classMirror = runtimeMirror.reflectClass(classSymbol)
val moduleSymbol = runtimeMirror.staticModule(className)
val moduleMirror = runtimeMirror.reflectModule(moduleSymbol)
val moduleInstanceMirror = runtimeMirror.reflect(moduleMirror.instance)
val defaultValueMethodSymbols = moduleMirror.symbol.info.members
.filter(_.name.toString.startsWith(ds.nme.defaultGetterName(ds.newTermName("apply"), 1).toString.dropRight(1)))
.toSeq
.reverse
.map(_.asMethod)
val defaultValueMethods = defaultValueMethodSymbols.map(moduleInstanceMirror.reflectMethod).toList
val primaryConstructorMirror = classMirror.reflectConstructor(classSymbol.primaryConstructor.asMethod)
primaryConstructorMirror.apply(defaultValueMethods.map(_.apply()): _*)
}

def main(args: Array[String]): Unit = {
val instance = newInstanceWithDefaultParameters(classOf[MyClass].getName)
println(instance)
}
}

case class MyClass(a: Int = 1, b: String = "foo")

Source code on Github.

Подписаться на мой блог

Мои записки о программировании. Я пишу редко.

Оставьте свою почту, чтобы не пропустить новые статьи