gpt4 book ai didi

Groovy - 将属性或方法动态添加到此元类

转载 作者:行者123 更新时间:2023-12-01 19:55:54 25 4
gpt4 key购买 nike

我想动态地将字段和方法添加到当前对象的 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"

长答案:

我认为,有 3 件事给你带来了问题。第一个是元类有一个全局注册表。第二个是 Groovy 允许每个实例元类(这是 Groovy 类的默认设置)。第三个是默认元类不允许运行时元编程。

因此,如果您进行运行时元编程,则默认值需要替换为 ExpandoMetaClass (EMC),以实现这一点。但由于存在每个实例元类逻辑,因此此替换可能不会影响所有实例。实例的元类在第一次使用时从全局注册表中获取。 Process.metaClass.testProp = "test" 更改全局保存的。任何已经具有元类的实例都不会知道更改,因此也不知道该属性。 this.metaClass.testProp = "test" 只会改变当前实例的元类,其他实例可能不知道。您可以使用 this.metaclass = null 来重置它。并且它将再次从全局注册表请求元类。如果您对每个实例进行了更改,则您的更改将消失。如果您进行了全局更改,则您的更改现在可见。

如果您使用 Groovy 中的默认元类 (MetaClassImpl),那么所有这些都很重要。如果您在代码中进行类似 a 的更改,则新的元类将是 ExpandoMetaClass (EMC)。该元类允许更改,因此进一步的更改不会导致元类的替换。为了确保所有实例从一开始就采用 ExpandoMetaClass,您通常具有如下所示的某种设置代码:ExpandoMetaClass.enableGlobally()

所以为了解决你的问题,我可以简单地这样做

Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"

如果您之前在某些设置代码中使用过ExpandoMetaClass.enableGlobally(),则可以将元类的重置代码保留在外(或者如果全局元类与“这个”以及如果是 EMC)。例如,Grails 默认使用 EMC

关于Groovy - 将属性或方法动态添加到此元类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32411927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com