Groovy-将属性或方法动态添加到此
我想向当前对象的Groovy-将属性或方法动态添加到此,groovy,Groovy,我想向当前对象的元类动态添加一个字段和方法。我试过了 this.metaClass.testProp = "test" 添加名为testProp的字段。然而,我明白了 groovy.lang.MissingPropertyException: No such property: testProp for class: groovy.lang.MetaClassImpl 当我在类级别执行相同操作时,例如,将testProp添加到类中,而不是直接添加到对象中 Process.metaClass.
元类
动态添加一个字段和方法。我试过了
this.metaClass.testProp = "test"
添加名为testProp
的字段。然而,我明白了
groovy.lang.MissingPropertyException: No such property: testProp for class: groovy.lang.MetaClassImpl
当我在类级别执行相同操作时,例如,将testProp添加到类中,而不是直接添加到对象中
Process.metaClass.testProp = "test"
它可以工作,但我的对象不会继承该字段。如果您有任何正确的想法或建议,我们将不胜感激。简短回答:
Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"
长答案:
Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"
我想,有三件事让你在这里成为一个问题。第一个是有一个元数据类的全局注册表。第二个是Groovy允许每个实例的元类(这是Groovy类的默认值)。第三个是默认的元类不允许运行时元编程
因此,如果执行运行时元编程,则需要将默认值替换为ExpandoMetaClass(EMC),以实现这一点。但由于存在每个实例的元类逻辑,这种替换可能不会影响所有实例。实例的元类在第一次使用时从全局注册表中获取Process.metaClass.testProp=“test”
更改全局保存的文件。任何已经有一个元类的实例都不知道更改,因此也不知道属性this.metaClass.testProp=“test”
将仅更改当前实例的元类,其他实例可能不知道它。您可以使用this.metaclass=null
重置它。它将再次从全局注册表请求元类。如果您进行了全局更改,您的更改现在可见
如果您使用Groovy中的默认元类(MetaClassImpl),所有这些都很重要。如果您在代码中做了类似的更改,那么新的元类将是ExpandoMetaClass(EMC)。这个元类允许更改,因此进一步的更改不会导致替换元类。为了确保所有实例从一开始就使用ExpandoMetaClass,您通常会有如下设置代码:ExpandoMetaClass.enableGlobal()
为了解决你的问题,我可以这么做
Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"
如果您以前在某些设置代码中使用了ExpandoMetaClass.enableglobal()
,则可以不使用meta类的重置代码(或者如果全局meta类与“this”的重置代码相同,并且是EMC的重置代码)。例如,Grails使用EMC作为默认值