首页 文章

动态添加的groovy属性并非每个实例都是唯一的

提问于
浏览
0

如果我动态地向类添加属性,则使用对相同值的引用初始化类的每个实例(即使属性正确地位于不同的地址,我不希望它们共享相同的引用值):

这是一个例子:

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,'normal'成员变量 planets 在创建两个对象时具有不同的地址 . 但是,动态添加的 dynamicPlanets 指向solarSystem1指向的同一对象(在本例中为地址66100363) .

我可以在我的动态getter( getUniqueDynamicPlanets )中重新分配它们,这可以解决问题 .

但是,我无法覆盖 getDynamicPlanets getter,因为我要么得到一个无限循环,要么我无法直接访问动态添加的属性 .

有没有办法直接访问动态添加的属性,所以我可以在 getDynamicPlanets getter中处理这个?对此有更好的策略吗?对不起,如果我错过了,我看了一堆......

谢谢

1 回答

  • 0

    我不是100%确定我理解你的问题,但如果我这样做,你是否尝试将 getDynamicPlanets 闭包设置为显式0参数,所以:

    SolarSystem.metaClass.getDynamicPlanets = {->  ... }
    

    如果你之前没有没有args的 -> ,则隐含的 it 参数's assigned and it'不是零arg方法,所以不遵守javabean getter / setter模式 .

相关问题