Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Groovy动态更改Java应用程序的行为_Java_Dynamic_Groovy - Fatal编程技术网

使用Groovy动态更改Java应用程序的行为

使用Groovy动态更改Java应用程序的行为,java,dynamic,groovy,Java,Dynamic,Groovy,我正在研究动态修改Java应用程序行为的方法(具体来说,我正在尝试制作一个Minecraft mod,允许用户通过编写代码来修改他们找到的对象的行为,而无需重新启动游戏),我偶然发现了Groovy。我的问题是:是否有可能以Java和Groovy“共享”对象的方式集成它们?(我正在考虑拥有一组实际上是Groovy代码的特定类,以便您可以在运行时更改代码,类似于您在任何Smalltalk实现中可以执行的操作)我不确定使用Groovy不必编译它就可以实现这一点。您可以这样做,但是Groovy的“脚本”

我正在研究动态修改Java应用程序行为的方法(具体来说,我正在尝试制作一个Minecraft mod,允许用户通过编写代码来修改他们找到的对象的行为,而无需重新启动游戏),我偶然发现了Groovy。我的问题是:是否有可能以Java和Groovy“共享”对象的方式集成它们?(我正在考虑拥有一组实际上是Groovy代码的特定类,以便您可以在运行时更改代码,类似于您在任何Smalltalk实现中可以执行的操作)

我不确定使用Groovy不必编译它就可以实现这一点。您可以这样做,但是Groovy的“脚本”方面对您没有帮助。我会考虑让玩家编写javascript并使用Java的
ScriptEngine
。请参见此处:

查看。它举例说明了如何从Java应用程序内部运行Groovy脚本,并使用
Groovy.lang.Binding

在它们之间共享数据。是的,您可以做到这一点。例如,您有一些用java编写的东西,它使用了spring上下文中的一些对象。所以现在你能做的是:

  • 在执行java代码之前执行groovy脚本
  • 使用委托设计模式对其进行包装,覆盖某些方法
  • 最后把它放回上下文中
所以基本上,在执行java代码的那个一刻,他会得到一个包装好的对象,并在运行时进行一些更改

如果这正是您想要做的,请告诉我我可以为您编写一些示例代码。

多么酷的想法

1。Groovy:Java和Groovy可以共享对象并来回调用。实现Java接口的Groovy类很容易从Java调用。(还有其他方法,比如从Java调用
groovyObject.invokeMethod(“methodName”,args)
)在JVM语言中,Groovy与Java的集成最紧密。Java程序员也很容易学习,因为它与Java共享了很多东西

这本书有一章是关于“集成Groovy”的,其中解释和比较了各种方法(比以前更详细):GroovyShell、GroovyScript引擎、GroovyClassLoader、Spring集成和JSR-223 ScriptEngineManager。GroovyClassLoader是最有能力的选择

然而,虽然在运行时编译和加载Groovy代码很容易,但我对如何更改现有对象实例的行为感到困惑(下面缺少关于热交换的说明)。(这可能取决于该类是重写Java接口还是子类化Java类。)考虑:

class G implements Runnable {
  void run() { println 'Groovy' }
}

g = new G()
g.run()
这将打印
Groovy
。现在重新定义类:

class G implements Runnable {
  void run() { println 'Groovy!' }
}

g1 = new G()
g.run()
g1.run()
这张照片

Groovy
Groovy!
Groovy
Groovy!
Groovy!
现在使用meta类在运行时更改方法:

G.metaClass.run = { println 'Groovy!!!' }

g2 = new G()
g.run()
g1.run()
g2.run()
这张照片

Groovy
Groovy!
Groovy
Groovy!
Groovy!
如果我们从这些类定义中省略了
实现Runnable
,那么最后一步将改为打印

Groovy
Groovy!
Groovy!!!
但对于我们实现Runnable的类,现在执行以下操作:

G.metaClass.run = { println 'Very Groovy!!!' }

g3 = new G()
g.run()
g1.run()
g2.run()
g3.run()
这张照片是:

 Groovy
 Groovy!
 Very Groovy!!!
 Very Groovy!!!
一个变通方法将在类变量中保存的闭包中实现这些方法

2。热交换:如果主要目的是在运行时为具有现有实例的类重新定义方法体,那么您只需在IDE的调试器中运行并使用热交换即可

例如,对于IntelliJ,下面是Java和Groovy代码的示例

3。扩展热插拔:如果您还希望能够在运行时添加/删除方法和实例变量,请通过DCEVM()查看

请参阅上的热插拔代码

也看到这个