如何在@Immutable类中设置超类属性?

时间:2015-12-09 15:33:37

标签: inheritance groovy immutability

鉴于

import groovy.transform.Immutable

class A {
  String a
}

@Immutable
class B extends A {
  String b
}

当我尝试使用地图构造函数

设置值时
def b = new B(a: "a", b: "b")

然后a仍为空:

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

是否可以在地图构造函数中定义一个考虑其超类属性的@Immutable类?

我使用的是Groovy 2.4.3

2 个答案:

答案 0 :(得分:3)

根据ImmutableASTTransformation的代码,createConstructorMapCommon方法添加的Map-arg构造函数不包含对方法体中super(args)的调用。

我不确定这个遗漏是故意的还是偶然的;无论如何,这个类需要进行修改才能实现您所寻找的目标。与此同时,我唯一的建议是使用合成而不是继承与@Delegate来简化对A属性的访问。

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

但是,由于A是可变的(即使我们在@Immutable注释中声明它是不可变的,B也变得可变,例如。

b.a = 'foo' // succeeds

答案 1 :(得分:0)

我也遇到了这个问题。您可以通过调用getter方法来解决它。groovy auto会自动为您添加属性,而不是直接访问该属性(在您的示例中为b.getA()而不是b.a)

这是一个愚蠢的例子。...

class base{
    def name;
    def myNameIs(){
         return name;//willl return null when called from extending class person
    }
    def extendersNameIs(){
       return getName()// will return extending class default value
    }
 }
 class person extends base{
     def name="betty"//override set default value
  }
  def m=new person();
  println m.myNameIs(); // outputs null
  println m.extendersNameIs();//outputs "betty"

查看实际情况https://groovyconsole.appspot.com/script/5193965758316544 这并非总是理想的解决方案,但这是一种解决方法。