在Scala中动态创建类,我应该使用解释器吗? [英] dynamically create class in scala, should I use interpreter?

查看:245
本文介绍了在Scala中动态创建类,我应该使用解释器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在运行时在 Scala 中创建一个类.现在,仅考虑一个简单的情况,即我想使具有某些属性的 java bean等效,我只在运行时知道这些属性.

I want to create a class at run-time in Scala. For now, just consider a simple case where I want to make the equivalent of a java bean with some attributes, I only know these attributes at run time.

如何创建scala类?如果有一种方法可以编译它并在运行时加载它,我愿意从scala源文件中创建,由于有些时候我想将某些复杂的函数添加到类中,所以我可能希望这样做. 我该怎么办?

How can I create the scala class? I am willing to create from scala source file if there is a way to compile it and load it at run time, I may want to as I sometimes have some complex function I want to add to the class. How can I do it?

我担心我所阅读的scala解释器会对加载的解释代码进行沙箱处理,以致托管解释器的一般应用程序无法使用它?如果是这种情况,那么我将无法使用动态加载的Scala类.

I worry that the scala interpreter which I read about is sandboxing the interpreted code that it loads so that it won't be available to the general application hosting the interpreter? If this is the case, then I wouldn't be able to use the dynamically loaded scala class.

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

Anyway, the question is, how can I dynamically create a scala class at run time and use it in my application, best case is to load it from a scala source file at run time, something like interpreterSource("file.scala") and its loaded into my current runtime, second best case is some creation by calling methods ie. createClass(...) to create it at runtime.

谢谢,菲尔

推荐答案

没有足够的信息来知道最佳答案,但是请记住您正在JVM上运行,因此对Java有效的任何技术或字节码工程库都应在这里也有效.

There's not enough information to know the best answer, but do remember that you're running on the JVM, so any techniques or bytecode engineering libraries valid for Java should also be valid here.

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

There are hundreds of techniques you might use, but the best choice depends totally on your exact use case, as many aren't general purpose. Here's a couple of ideas though:

  • 对于一个简单的bean,您也可以 只需使用地图,或查看 来自Apache Commons的DynaBean类.

  • For a simple bean, you may as well just use a map, or look into the DynaBean class from apache commons.

有关更高级的行为,您可以 显式调用编译器,然后 然后获取生成的.class文件 通过类加载器(这在很大程度上 JSP如何做到)

For more advanced behaviour you could invoke the compiler explicitly and then grab the resulting .class file via a classloader (this is largely how JSPs do it)

解析器和自定义DSL非常适合 某些情况下.豆壳也一样 脚本.

A parser and custom DSL fit well in some cases. As does bean shell scripting.

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

Check out the ScalaDays video here: http://days2010.scala-lang.org/node/138/146 which demonstrates the use of Scala as a JSR-223 compliant scripting language. This should cover most scenarios where you'd want to evaluate Scala at runtime.

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

You'll also want to look at the email thread here: http://scala-programming-language.1934581.n4.nabble.com/Compiler-API-td1992165.html#a1992165

其中包含以下示例代码:

This contains the following sample code:

// 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 )) 

这篇关于在Scala中动态创建类,我应该使用解释器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆