Magnolia Tech

いつもコードのことばかり考えている人のために。

Scalaでリフレクションを使って、与えられた型情報から動的にオブジェクトを生成する

Scalaでも動的にオブジェクトを生成したいですね、そうですね。

早速リフレクションを使って動的にオブジェクトを生成します。

以下、覚え書き…もう少し効率よくできる気がする。

import scala.reflect.runtime.{universe => ru}
import ru._

case class Person(name: String)

object ReflectionTest {
  def main(args: Array[String]): Unit = {


    def generate[T](implicit tag: TypeTag[T]): T = {

      val typeSymbol          = typeOf[T].typeSymbol            // 型のSymbolを得る
      val companionSymbol     = typeSymbol.companion            // コンパニオンオブジェクトのsymbolが取れる
      val companionType       = companionSymbol.typeSignature   // symbolからコンパニオンオブジェクトのTypeが取れる
      val applyMethodSymbol   = companionType.decl(TermName("apply")).asMethod  // applyメソッドのmethodSymbolを得る

      val mirror = scala.reflect.runtime.currentMirror            // 現在のミラーを取得する

      val mm = mirror.reflectModule(companionSymbol.asModule)     // オブジェクトのmodule mirrorを取得する
      val im = mirror.reflect(mm.instance)                        // module mirrorのインスタンスからinstance mirrorを取得する
      val methodMirror = im.reflectMethod(applyMethodSymbol)      // instance mirrorからmethod mirrorを取得する

      methodMirror("John").asInstanceOf[T]  // 実行する…applyメソッドなので、戻り値はAnyに入ったオブジェクト…型を指定して返す
    }

    println(generate[Person]) // 生成したオブジェクトが得られる
  }
}