Reputation: 15909
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?
Upvotes: 4
Views: 3252
Reputation: 1
I think, You should use @MapConstructor annotation
@ToString(includePackage = false, includeNames = true)
@MapConstructor
class A {
@Final
String x
int y
}
def a = new A(x: 'david', y: 12)
println "a = $a"
Upvotes: 0
Reputation: 1131
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
Upvotes: 9
Reputation: 187499
I don't know why your constructor with a Map argument doesn't work, but this constructor does:
class Foo {
final x
Foo(x) {
this.x = x
}
}
def foo = new Foo(1)
Upvotes: 1