在scala中动态创建类,我应该使用解释器吗?

Phi*_*hil 12 interpreter scala runtime javabeans

我想在Scala中运行时创建一个类.现在,只考虑一个简单的例子,我想用相似的java bean来创建一些属性,我只在运行时知道这些属性.

如何创建scala类?我愿意从Scala的源文件创建,如果有编译它,并在运行时加载的方式,我可能要为我有时候有一些复杂的功能,我想添加到类.我该怎么做?

我担心我读到的scala解释器是沙盒化它加载的解释代码,以便托管解释器的一般应用程序无法使用它?如果是这种情况,那么我将无法使用动态加载的scala类.

无论如何,问题是,如何在运行时动态创建一个scala类并在我的应用程序中使用它,最好的情况是在运行时从scala源文件加载它,类似于interpreterSource("file.scala")它并加载到我当前的运行时,第二最好的情况是通过调用方法来创建. createClass(...)在运行时创建它.

谢谢,菲尔

Kev*_*ght 8

没有足够的信息来了解最佳答案,但请记住您在JVM上运行,因此任何适用于Java的技术或字节码工程库在此处也应该有效.

您可能会使用数百种技术,但最佳选择完全取决于您的确切用例,因为许多技术不是通用的.这里有几个想法:

  • 对于一个简单的bean,你也可以只使用一个map,或者从apache commons查看DynaBean类.

  • 对于更高级的行为,您可以显式调用编译器,然后通过类加载器获取生成的.class文件(这主要是JSP执行的方式)

  • 在某些情况下,解析器和自定义DSL非常适合.和bean shell脚本一样.

在这里查看ScalaDays视频:http://days2010.scala-lang.org/node/138/146 ,它演示了如何使用Scala作为JSR-223兼容的脚本语言.这应该涵盖您希望在运行时评估Scala的大多数情况.

您还需要查看此处的电子邮件主题:http://scala-programming-language.1934581.n4.nabble.com/Compiler-API-td1992165.html#a1992165

这包含以下示例代码:

// We currently call the compiler directly 
// To reduce coupling, we could instead use ant and the scalac ant task 

import scala.tools.nsc.{Global, Settings} 
import scala.tools.nsc.reporters.ConsoleReporter
{ 
  // called in the event of a compilation error 
  def error(message: String): Nothing = ... 

  val settings = new Settings(error) 
  settings.outdir.value = classesDir.getPath 
  settings.deprecation.value = true // enable detailed deprecation warnings 
  settings.unchecked.value = true // enable detailed unchecked warnings 

  val reporter = new ConsoleReporter(settings) 

  val compiler = new Global(settings, reporter) 
  (new compiler.Run).compile(filenames) 

  reporter.printSummary 
  if (reporter.hasErrors || reporter.WARNING.count > 0) 
  { 
             ... 
  } 
} 


val mainMethod: Method = { 
  val urls = Array[URL]( classesDir.toURL ) 

  val loader = new URLClassLoader(urls) 

  try { 
    val clazz: Class = loader.loadClass(...) 

    val method: Method = clazz.getMethod("main", Array[Class]( classOf[Array[String]] )) 
    if (Modifier.isStatic(method.getModifiers)) { 
       method 
    } else { 
      ... 
    } 
  } catch { 
    case cnf: ClassNotFoundException => ... 
    case nsm: NoSuchMethodException => ... 
  } 
} 

mainMethod.invoke(null, Array[Object]( args )) 
Run Code Online (Sandbox Code Playgroud)