【问题标题】:groovy metaclass overriding properties not workinggroovy 元类覆盖属性不起作用
【发布时间】:2021-01-11 09:06:51
【问题描述】:
static void main(String[] args) {
    ExpandoMetaClass.enableGlobally()
    A a=new A()
    add(a, "a", "a")
    add(a,"a",1)
    add(a,"a",new Date())
    a.getProperties().entrySet().forEach({ entry -> println("${entry.getKey()} ${entry.getValue()}") })
}
static void add(A a, String key, Object value) {
    if (a.hasProperty(key)) {
        a.metaClass."${key}"=value
        if (!Objects.equals(a.getProperty(key), value)) {
            System.err.println("error,key:${key},value:${value}")
        }
    } else {
        a.metaClass."${key}"=value
    }
}
static class A{

}

输出:

error,key:a,value:Mon Jan 11 16:43:48 CST 2021
class class com.huya.TypeTest$A
a 1

add(a,"a",new Date())

似乎不起作用,我找不到任何关于它的问题。 以及“xx.metaClass.a=1”是如何工作的,有相关资料吗?

【问题讨论】:

  • 您到底期待什么?你能描述一下你想要做什么吗?为什么没有元类就无法完成?
  • 期望:第一次,a="a" then,a=1 last,a=new Date() 但是,第一次和第二次成功,第三次是失败,这是一个简单的分配

标签: java groovy metaprogramming


【解决方案1】:

据我了解,当您动态创建属性时,它只是简单地声明 (MetaBeanProperty) 并且在您获取/设置它之前不会具体化 - 之后它会变成 CachedField

因此假设以下是您的代码的简化版本(您可以将其直接粘贴到 GroovyConsole):

class A {}

static void add(A a, String key, Object value) {
    a.metaClass."${key}" = value
}

现在它可以像您想象的那样工作了:

Date date = new Date()
A a1 = new A()
add(a1, 'x', 1)
add(a1, 'x', 'foobar')
add(a1, 'x', date)
assert a1.x == date

那是因为您仅在最后一行 (assert a1.x) 获得值(实现声明)。

另一个例子(它更像你发布的原始代码,即在第二次以上调用时执行getProperty()。)请注意add() 不像前面的例子那样工作,因为在第一次调用,声明的属性被物化(assert a2.x)。

A a2 = new A()
add(a2, 'x', 1);         assert a2.x == 1
add(a2, 'x', 'foobar');  assert a2.x == 1
add(a2, 'x', date);      assert a2.x == 1

一旦属性被具体化,您可以简单地使用普通的 Groovy 语法或setProperty 为其分配值,以防名称是动态的。

A a3 = new A()
add(a3, 'x', 1);                   assert a3.x == 1
a3.x = 100;                        assert a3.x == 100
a3.setProperty('x', 200);          assert a3.x == 200
a3.x = date;                       assert false, 'should have thrown a GroovyCastException'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 2018-11-17
    • 2018-06-22
    • 1970-01-01
    • 2014-04-30
    • 2017-05-02
    • 1970-01-01
    相关资源
    最近更新 更多