有没有办法从在同一脚本中声明的类的静态方法访问脚本中声明的全局变量?
例如
def s = "12345"
class MyClass {
static def method() {
println s
}
}
因为这样它就会失败并出现错误
You attempted to reference a variable in the binding or an instance variable from a static context
不过这是意料之中的。
这个问题有一个相关的讨论:
时髦的作用域 - 如何在方法中访问脚本变量
相关的是,这两个问题都是指在类中使用全局变量,但这个问题有些不同,因为您正在寻求使用静态方法,该方法会改变传递脚本实例或绑定的方式(2 种选择(。
传递脚本的实例
import groovy.transform.Field
@Field def s = "12345"
class MyClass {
static def method(si) {
return si.s
}
}
assert MyClass.method(this) == "12345"
传递脚本的绑定
s = "12345" // NOTE: no 'def'
class MyClass {
static def method(b) {
return b.s
}
}
assert MyClass.method(binding) == "12345"
好吧,问题是在Groovy中没有全局变量这样的东西。松散地认为是全局变量的东西实际上是某个类中的静态属性。
例如,如果您删除 println 行以便编译代码,则会从编译器中得到如下所示的内容:
public class script1455567284805 extends groovy.lang.Script {
...
public java.lang.Object run() {
return java.lang.Object s = '12345'
}
...
}
public class MyClass implements groovy.lang.GroovyObject extends java.lang.Object {
...
public static java.lang.Object method() {
// This is where the println would have been.
return null
}
...
}
如您所见,将创建一个附加类,并在该类的方法run()
中声明s
变量。这使得其他类无法访问该变量。
注意:删除def
无法解决此问题。
溶液
最好的办法是将"全局变量"放入一个类中,可能作为静态属性,如下所示:
class Global {
static Object S = "12345"
}
class MyClass {
static def method() {
println Global.S
}
}
您在s
变量中包含一个变量类型(通过使用def
类型(。在Groovy脚本中,这被视为局部变量 - 并且是生成的run()
方法的局部变量 - 这有点像main()
类。因此,该变量在其他方法或类中不可用。
如果删除def
您将能够使用 s
变量。
这是进一步解释这一点的Groovy文档。