如何在Groovy中向闭包动态添加属性?

时间:2018-08-03 12:33:21

标签: groovy

我的环境是Groovy版本:2.5.1 JVM:1.8.0_151

如您所知,您可以向此类动态添加属性或方法:

class Cat {
}

def cat = new Cat()

cat.metaClass.name = "Amy"
cat.metaClass.greet = { println "Hello"}

println cat.name
cat.greet()

运行正常。但是当涉及到这样的关闭时:

def cat = {}

cat.metaClass.name = "Amy"
cat.metaClass.greet = { println "Hello"}

println cat.name
cat.greet()

它给出了这样的错误:

捕获:groovy.lang.MissingPropertyException:无此类属性:类的名称:org.codehaus.groovy.runtime.metaclass.ClosureMetaClass groovy.lang.MissingPropertyException:无此类属性:类的名称:org.codehaus.groovy.runtime.metaclass.ClosureMetaClass     在test.run(test.groovy:7)

为什么?闭包也是Groovy中的对象...

2 个答案:

答案 0 :(得分:2)

对于您的错误或以下代码段,Groovy对闭包使用一种特定形式的元类,称为“ ClosureMetaClass”:

    def t = {}
    def t2 = new Object()

    println t.metaClass.class.simpleName // ClosureMetaClass
    println t2.metaClass.class.simpleName // HandleMetaClass

之所以会发生这种情况,是因为Groovy在语言本身内部有一个特定的方法,该方法根据传递的Classtype返回带有签名的MetaClass:

MetaClass getMetaClass(Class var1);

看看groovy's official documentation,ClosureMetaClass仅用于“内部使用”。因此,您无法在运行时为其添加任何方法。

您将能够向Closure类本身的metaClass添加方法。参见here

答案 1 :(得分:0)

删除metaClass

我在本地运行了它,并且奏效了。我自己还在学习groovy,所以我不知道它为什么起作用。我想这是由于基本关闭没有metaClass信息造成的。

def cat = {}

cat.name = "Amy"
cat.greet = { println "Hello"}

println cat.name
cat.greet()