如果我动态地向类添加属性,则使用对相同值的引用初始化类的每个实例(即使属性正确地位于不同的地址,我不希望它们共享相同的引用值):
以下是一个例子:
class SolarSystem {
Planets planets = new Planets()
static main(args) {
SolarSystem.metaClass.dynamicPlanets = new Planets()
// Infinite loop
// SolarSystem.metaClass.getDynamicPlanets = {
// if (!delegate.dynamicPlanets.initialized) {
// delegate.dynamicPlanets = new Planets(initialized: true)
// }
//
// delegate.dynamicPlanets
// }
// No such field: dynamicPlanets for class: my.SolarSystem
// SolarSystem.metaClass.getDynamicPlanets = {
// if (!delegate.@dynamicPlanets.initialized) {
// delegate.@dynamicPlanets = new Planets(initialized: true)
// }
//
// delegate.@dynamicPlanets
// }
SolarSystem.metaClass.getUniqueDynamicPlanets = {
if (!delegate.dynamicPlanets.initialized) {
delegate.dynamicPlanets = new Planets(initialized: true)
}
delegate.dynamicPlanets
}
// SolarSystem.metaClass.getDynamicPlanets = {
// throw new RuntimeException("direct access not allowed")
// }
def solarSystem1 = new SolarSystem()
println "a ${solarSystem1.planets}"
println "b ${solarSystem1.dynamicPlanets}"
println "c ${solarSystem1.uniqueDynamicPlanets}"
println "d ${solarSystem1.dynamicPlanets}"
println ''
def solarSystem2= new SolarSystem()
println "a ${solarSystem2.planets}"
println "b ${solarSystem2.dynamicPlanets}"
println "c ${solarSystem2.uniqueDynamicPlanets}"
println "d ${solarSystem2.dynamicPlanets}"
}
}
在另一个文件中:
class Planets {
boolean initialized = false
}
当它运行时,您会看到如下内容:
a my.Planets@4979935d
b my.Planets@66100363
c my.Planets@5e0feb48
d my.Planets@5e0feb48
a my.Planets@671ff436
b my.Planets@66100363
c my.Planets@651dba45
d my.Planets@651dba45
请注意,对于solarSystem2,“普通”成员变量行星在创建两个对象时具有不同的地址。但是,动态添加的 dynamicPlanets 指向solarSystem1指向的同一对象(在本例中为地址66100363)。
我可以在动态getter( getUniqueDynamicPlanets )中重新分配它们,这样可以解决问题。
但是,我无法覆盖 getDynamicPlanets getter,因为我要么获得无限循环,要么无法直接访问动态添加的属性。
有没有办法直接访问动态添加的属性,所以我可以在 getDynamicPlanets getter中处理这个问题?对此有更好的策略吗?对不起,如果我错过了,我看了一堆......
由于
答案 0 :(得分:0)
我不是100%确定我理解你的问题,但如果我这样做,你是否尝试将getDynamicPlanets
闭包设置为显式为0参数,所以:
SolarSystem.metaClass.getDynamicPlanets = {-> ... }
如果你之前没有没有args的->
,则会分配一个隐式it
参数,并且它不是零arg方法,所以不遵守javabean getter / setter模式。