以前我认为 Groovy 中的属性是通过省略作用域关键字来指示的。换句话说
class Test {
def prop = "i am a property"
public notProp = "i am not"
}
但是,看来我对此不正确,因为以下脚本打印“getter val”
class Foo {
public bar = "init val"
public getBar() {
"getter val"
}
}
println new Foo().bar
bar
访问时调用 getter 的事实表明这bar
是一个属性而不是字段。那么 Groovy 中的字段和属性到底有什么区别呢?
谢谢,唐
为了直接访问字段,您必须在其前面添加 @ 符号:
assert "getter val" == new Foo().bar
assert "init val" == new Foo().@bar
作品的简短形式new Foo().getBar()
虽然bar
不是一种财产,但在我看来仍然是简洁的。
相反,您无法调用foo.setBar("setter val")
,但如果您将其定义bar
为不带访问修饰符的属性,则可以调用。
您正在寻找 groovy 中不存在的差异。
使用修饰符确实会抑制属性的创建。让您感到困惑的是,.
当不存在这样的属性时,似乎会回退到字段访问。
$ 格罗维什 Groovy 外壳(2.1.0,JVM:1.7.0_21) 输入“help”或“\h”以获得帮助。 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ---------------------------- groovy:000> 类 A { def a = "foo" }; ===> 正确 groovy:000> 新 A().getA() ===> 富 groovy:000> 新 A().a ===> 富 groovy:000> 新 A().properties ===> {class=A 类,a=foo}
但:
groovy:000> 类 A { public def a = "foo" }; ===> 正确 groovy:000> 新 A().getA() 错误 groovy.lang.MissingMethodException: 无方法签名:A.getA() 适用于参数类型:() 值:[] 可能的解决方案: getAt(java.lang.String)、grep()、grep(java.lang.Object)、with(groovy.lang.Closure)、putAt(java.lang.String、java.lang.Object)、等待() 在 groovysh_evaluate.run (groovysh_evaluate:2) ... groovy:000> 新 A().a ===> 富 groovy:000> 新 A().properties ===> {类=A类}
我认为@Christoph Metzendorf 的答案是正确的......
为了直接访问字段,您必须在其前面添加 @ 符号:
assert "getter val" == new Foo().bar assert "init val" == new Foo().@bar
...但我想补充一点,在您的Foo
示例中,您的getBar
方法覆盖了getBar
Groovy 为您生成的方法。bar
如果您想继续覆盖 Groovy 为您生成的默认方法,您可以使用上述语法直接访问getBar
,或者您可以不覆盖,getBar
这样任何调用都getBar
将使用 Groovy 为您生成的 getter。
它们可能看起来相同并且大部分行为相同,但 Groovy 只会为属性生成 getter/setter,该属性是通过访问修饰符的存在来定义的。