Search code examples
grailsgroovy

Groovy and final properties how to set with a Map?


i am trying to set final properties in Groovy source (used in a Grails project) and following some examples but somehow i does not seem to work and i cannot find out why..

class Foo {

  final x

  Foo(Map m=[:]) {
    m.each { key, value -> this.@"$key" = value }
  }
}

def foo = new Foo(x:1)

I am getting the error:

Cannot set the property 'x' because the backing field is final.

According to some posts found on the internet this should work. Why does fail how can is set the properties via a map when using a final field?


Solution

  • You can achieve the result you seek by using the @Immutable annotation

    @Immutable
    class Foo {
      def x
    }
    

    Then this can be called as

    def foo = new Foo([:])
    

    or

    def foo = new Foo(x:42)
    

    and then later

    foo.x = 43
    

    causes

    ERROR groovy.lang.ReadOnlyPropertyException:
    Cannot set readonly property: y for class: Foo