Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set super class properties in @Immutable classes?

Given

import groovy.transform.Immutable

class A {
  String a
}

@Immutable
class B extends A {
  String b
}

When I try to set the values using the map constructor

def b = new B(a: "a", b: "b")

then a ist still null:

groovy:000> b = new B(a: "a", b: "b")
===> B(b)
groovy:000> b.b
===> b
groovy:000> b.a
===> null

Is it possible to define an @Immutable class which considers the properties of its super classes in the map constructor?

I am using Groovy 2.4.3

like image 211
Beryllium Avatar asked Sep 26 '22 00:09

Beryllium


1 Answers

Based on the code for the ImmutableASTTransformation, the Map-arg constructor added by the createConstructorMapCommon method does not include a call to super(args) in the method body.

I'm not sure if this omission is intentional or accidental; regardless, this class would need to be modified in order to achieve what you're looking for. In the meantime, my only suggestion is to use composition instead of inheritance with @Delegate to simplify access to A's properties.

import groovy.transform.*

@TupleConstructor
class A {
  String a
}

@Immutable(knownImmutableClasses=[A])
class B {
  @Delegate A base
  String b
}

def b = new B(base: new A("a"), b: "b")
println b.a

However, since A is mutable (even though we declare it immutable in the @Immutable annotation, B becomes mutable, too, e.g.

b.a = 'foo' // succeeds
like image 104
bdkosher Avatar answered Dec 31 '22 22:12

bdkosher