gpt4 book ai didi

grails - Groovy getProperties() 调用为不存在的属性调用 getter 超过 1000 次

转载 作者:行者123 更新时间:2023-12-02 13:46:05 24 4
gpt4 key购买 nike

在进行重构时遇到了这个问题。对 getProperties() 的调用导致我们的 CPU 使用率飙升。我们发现,如果您有一个没有关联属性的 getter,当您调用 getProperties() 时,该 getter 会被调用超过 1000 次。修复/解决方法很明显,我们知道它与元编程有关,但为什么会发生这种情况(groovy 源代码中的哪一点)?请参阅下面的 groovy 脚本代码:

class tester {

int count = 0

public getVar() {
println count++ + " getVar() called!"
return var
}
}

def t = new tester()

t.getProperties()

println "done!"

您应该看到 getVar() 被调用超过 1000 次。 1068 对我们来说是准确的。

最佳答案

这个问题可能已经在评论中得到了回答,但我更深入地回答了“groovy 源代码中的什么点”部分。

当您调用 getProperties()tester 的实例上Groovy 将发挥它的魔力并最终调用 DefaultGroovyMethods#getProperties(Object)其中(在 Groovy 2.4.7 中)如下所示:

public static Map getProperties(Object self) {
List<PropertyValue> metaProps = getMetaPropertyValues(self); // 1
Map<String, Object> props = new LinkedHashMap<String, Object>(metaProps.size());

for (PropertyValue mp : metaProps) {
try {
props.put(mp.getName(), mp.getValue()); // 2
} catch (Exception e) {
LOG.throwing(self.getClass().getName(), "getProperty(" + mp.getName() + ")", e);
}
}
return props;
}

首先,Groovy 确定给定对象的元属性(参见 1)。这将返回三个属性:
  • var :只有 getter (getVar()),没有 setter,没有字段
  • class : 仅 getter (继承自 Object ),没有 setter,没有字段
  • count :getter、setter(均由 Groovy 生成)和字段

  • 您可以通过调用 t.getMetaPropertyValues() 轻松验证这一点。 .

    接下来,Groovy 尝试获取每个属性的当前值并将其放入映射中(参见 2)。当它到达 var ,它记得 var有一个 setter/getter (即 getVar() )并调用它。 getVar()但是,返回 var再次。对于 Groovy,这与第一步中确定的属性完全相同。再一次,它调用它的 getter getVar()无限循环开始。

    在某些时候,取决于 JVM,这会导致 StackOverflowError ,这正是这个网站的全部内容:-D

    关于grails - Groovy getProperties() 调用为不存在的属性调用 getter 超过 1000 次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34928892/

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