Dynamically compiling scala class files at runtime in Scala 2.11

人走茶凉 提交于 2019-11-27 12:30:21

If your goal is to run external scala classes in runtime, I'd suggest using eval with scala.tools.reflect.ToolBox (it is included in REPL, but for normal usage you have to add scala-reflect.jar):

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
tb.eval(tb.parse("""println("hello!")"""))

You also can compile files, using tb.compile.

Modified with example: assume you have external file with

class PersonData() {
  val field = 42
}
scala.reflect.classTag[PersonData].runtimeClass

So you do

val clazz = tb.compile(tb.parse(src))().asInstanceOf[Class[_]]
val ctor = clazz.getDeclaredConstructors()(0)
val instance = ctor.newInstance()

Additional possibilities are (almost) unlimited, you can get full tree AST and work with it as you want:

showRaw(tb.parse(src)) // this is AST of external file sources
// this is quasiquote
val q"""
      class $name {
        ..$stats
      }
      scala.reflect.classTag[PersonData].runtimeClass
    """ = tb.parse(src)
// name: reflect.runtime.universe.TypeName = PersonData
// stats: List[reflect.runtime.universe.Tree] = List(val field = 42)
println(name) // PersonData

See official documentation for these tricks:

http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html

http://docs.scala-lang.org/overviews/quasiquotes/intro.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!