Dónal
Dónal

Reputation: 187399

Groovy property definition

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

Answers (4)

ubiquibacon
ubiquibacon

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

Artefacto
Artefacto

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

Christoph Metzendorf
Christoph Metzendorf

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

Ted Naleid
Ted Naleid

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

Related Questions