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

发布于 2024-08-31 04:31:23 字数 506 浏览 5 评论 0原文

我想在 Scala 运行时创建一个类。现在,只考虑一个简单的情况,我想制作一个具有某些属性的 java bean 的等价物,我只在运行时知道这些属性。

如何创建 scala 类?如果有一种方法可以编译它并在运行时加载它,我愿意从 scala 源文件创建,我可能想要这样做,因为有时我想将一些复杂的函数添加到类中。 我该怎么做?

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

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

谢谢,菲尔

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.

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?

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.

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.

Thanks, Phil

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

划一舟意中人 2024-09-07 04:31:23

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

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

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

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

  • 解析器和自定义 DSL 非常适合
    一些情况。和豆壳一样
    脚本编写。

在此处查看 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 )) 

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:

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

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

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

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.

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 )) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文