Reputation: 187399
Previously I'd thought that a property in Groovy is indicated by the omission of a scoping keyword. In other words
class Test {
def prop = "i am a property"
public notProp = "i am not"
}
However, it appears I'm incorrect about this, because the following script prints "getter val"
class Foo {
public bar = "init val"
public getBar() {
"getter val"
}
}
println new Foo().bar
The fact that the getter is invoked when bar
is accessed suggests that bar
is a property rather than a field. So what exactly is the difference between fields and properties in Groovy.
Thanks, Don
Upvotes: 6
Views: 3116
Reputation: 10677
I think @Christoph Metzendorf answer was correct...
In order to access a field directly you have to prepend it with an @ sign:
assert "getter val" == new Foo().bar assert "init val" == new Foo().@bar
... but I would add that in your Foo
example your getBar
method overrode the getBar
method that Groovy generated for you. You can use the above syntax to access bar
directly if you want to continue overriding the default getBar
method Groovy generated for you, or you could just not override getBar
so any call to getBar
will use the getter Groovy generated for you.
Upvotes: 0
Reputation: 97845
Using a modifier does indeed suppress the creation of a property. What is confusing you is that .
seems to fallback on a field access when no such a property exists.
$ groovysh Groovy Shell (2.1.0, JVM: 1.7.0_21) Type 'help' or '\h' for help. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- groovy:000> class A { def a = "foo" }; ===> true groovy:000> new A().getA() ===> foo groovy:000> new A().a ===> foo groovy:000> new A().properties ===> {class=class A, a=foo}
But:
groovy:000> class A { public def a = "foo" }; ===> true groovy:000> new A().getA() ERROR groovy.lang.MissingMethodException: No signature of method: A.getA() is applicable for argument types: () values: [] Possible solutions: getAt(java.lang.String), grep(), grep(java.lang.Object), with(groovy.lang.Closure), putAt(java.lang.String, java.lang.Object), wait() at groovysh_evaluate.run (groovysh_evaluate:2) ... groovy:000> new A().a ===> foo groovy:000> new A().properties ===> {class=class A}
Upvotes: 1
Reputation: 8078
In order to access a field directly you have to prepend it with an @ sign:
assert "getter val" == new Foo().bar
assert "init val" == new Foo().@bar
That the short form of new Foo().getBar()
works, although bar
is not a property, is still concise from my point of view.
In contrast you can't make a call to foo.setBar("setter val")
, but you could in case you would have defined bar
as a property without the access modifier.
Upvotes: 3
Reputation: 26821
You're looking for a difference that isn't there in groovy.
"In Groovy, fields and properties have been merged so that they act and look the same."
Upvotes: 1