2012-02-11 16 views
0

我想知道是否有一种方法让Binding对象存储对象的引用,而不是复制一个对象?在执行setVariable时,GroovyShell绑定是否可以传递对象的引用?

Binding b = new Binding() 
String test = "test" 
b.setVariable("sth", test) 
test = "blah" 
GroovyShell gs = new GroovyShell(b) 
gs.evaluate("print(sth)") 

不幸的是,它打印“测试”。

有没有办法在groovy中做到这一点?

编辑:

我给的例子是错误的,太简单了。

我想我的问题发生是因为我在一个线程中实例化对象并在另一个线程中运行脚本。

class Test { 


[...] // field declarations 

    public Test(String name, String url, def params, String validateScript, String afterTestScript, GroovyShell shell) { 

[...] //just assigning params to fields 

     shell.setVariable("current", this) 
    } 


    void action() { 


     response = "something" 

    } 

    void validate() { 
     //shell.setVariable("current", this) 
    } 

    void afterTest() { 
     if (afterTestScript) shell.evaluate(afterTestScript) 
    } 

} 

所以测试对象在一个线程创建的,然后我把它作为一个Runnable对象,然后调用actionvalidateafterTest方法提供了参照。 如果我在构造函数中注释掉对setVariable的调用,并取消注释validate中的调用,它将正常工作。

它可能是一个并发“问题”? 在afterTestScript中,我只想打印响应字符串。

回答

0

我在自己创建新线程时遇到了这个问题。 一旦我开始使用线程池,问题就消失了。

这很可能是因为其他一些变化,但这是我看到干扰groovy shell的唯一变化。

最后,我们停止使用groovy shell来评估字符串,并开始将它们解析为脚本来运行它们。这是一个巨大的性能增益。

0

问题的本质实际上是由于您的对象引用在设置后发生更改。如果你想在分配它后改变它,那么你需要一个包装对象。例如。而不是

String test = "test" 
b.setVariable("sth", test) 
test = "blah" 
GroovyShell gs = new GroovyShell(b) 

使用

class MyWapper { 
    public String myText 
    public MyWrapper(String text){ 
    this.myText = text; 
    } 
} 

MyWrapper test = new MyWrapper("test") 
b.setVariable("sth", test) 
test.myText = "blah" 
GroovyShell gs = new GroovyShell(b) 
相关问题