首页 文章

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

提问于
浏览
1

我的环境是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 test.run中的.ClosureMetaClass(test.groovy:7)

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

2 回答

  • 0

    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是"internal usage only" . 因此,您无法在运行时添加任何方法 .

    您可以将方法添加到Closure类本身的metaClass中 . 见here .

  • 2

    删除 metaClass .

    我在本地运行它,它工作 . 我'm still learning groovy myself, so I don't知道它为什么有效 . 我想这是由于基本关闭没有 metaClass 信息 .

    def cat = {}
    
    cat.name = "Amy"
    cat.greet = { println "Hello"}
    
    println cat.name
    cat.greet()
    

相关问题