鉴于
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
答案 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 这并非总是理想的解决方案,但这是一种解决方法。