【问题标题】:Dynamically added groovy property is not unique per-instance动态添加的 groovy 属性不是每个实例唯一的
【发布时间】:2012-07-11 19:53:46
【问题描述】:

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

这是一个例子:

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

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

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

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

谢谢

【问题讨论】:

    标签: groovy metaprogramming


    【解决方案1】:

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

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

    如果您没有前面没有参数的->,则分配了一个隐式it 参数,它不是零参数方法,因此不遵守javabean getter/setter 模式。

    【讨论】:

    • 嗯,这很好。我会尝试一下,看看它是否会改变任何东西。有趣的是,我的 getter 确实被使用了,无论如何。
    • 好吧,不幸的是这并没有改变任何东西,但感谢您的提示!
    猜你喜欢
    • 2011-09-27
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2014-12-07
    • 2020-11-24
    相关资源
    最近更新 更多