groovy - metaClass.methods 和 metaClass.metaMethods 有什么区别?

标签 groovy metaprogramming

如果我向类添加元方法,我希望它显示在 Class.metaClass.metaMethods 中。 .但情况似乎并非如此。特别是,如果我这样做:

class Example {
    def realFoo() { "foo" }

}
Example.metaClass.metaFoo = { -> "foo" }

def reals = Example.metaClass.methods*.name.grep{it.contains("Foo")}
def metas = Example.metaClass.metaMethods*.name.grep{it.contains("Foo")}

println "reals = $reals, metas = $metas"

我希望输出 reals = [realFoo], metas = [metaFoo] ,但我实际上得到了 reals = [realFoo, metaFoo], metas = [] .

看起来新的元方法存储在方法中,而不是元方法中。那么,metaClass.methods 和有什么区别?和 metaClass.metaMethods ?

最佳答案

MetaMethods 包含那些由 Groovy 在类上修饰的方法,但实际上不是类的直接部分或其继承结构,或者已经通过元类手动插入到类中的方法。

这些定义在 DefaultGroovyMethods 中类(class)。

根据您实例化的对象类型,它主要是迭代器,如 each、collect、find 等。

对代码的这种修改显示了仅限元、仅限“真实”和共享的方法:

class Example {
    def realFoo() { "foo" }

}
Example.metaClass.metaFoo = { -> "foo" }

def reals = Example.metaClass.methods.name.sort().unique()
def metas = Example.metaClass.metaMethods.name.sort().unique()

def metaOnly = metas - reals
def realOnly = reals - metas
def shared = reals.findAll { metas.contains(it) }

println """
metaOnly = $metaOnly
realOnly = $realOnly
shared = $shared
"""

结果:
metaOnly = [addShutdownHook, any, asBoolean, asType, collect, dump, each, eachWithIndex, every, find, findAll, findIndexOf, findIndexValues, findLastIndexOf, findResult, getAt, getMetaPropertyValues, getProperties, grep, hasProperty, identity, inject, inspect, is, isCase, iterator, metaClass, print, printf, println, putAt, respondsTo, sleep, split, sprintf, use, with]
realOnly = [equals, getClass, getProperty, hashCode, metaFoo, notify, notifyAll, realFoo, setProperty, wait]
shared = [getMetaClass, invokeMethod, setMetaClass, toString]

所有的 metaOnly 和共享方法都在 DefaultGroovyMethods 中。所有“真正的”方法都在类本身或它的父类(在这种情况下为 Object)上,加上一些与元类直接相关的常规方法来获取/设置元类以及 getProperty/setProperty 和 invokeMethod这允许您覆盖方法行为。

如果您想搜索所有方法以查看存在的内容,我会使用以下内容:
def allMethods = (Example.metaClass.methods + Example.metaClass.metaMethods).name.sort().unique() 

关于groovy - metaClass.methods 和 metaClass.metaMethods 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4890136/

相关文章:

groovy - 在 Groovy 中将集合拆分为子集合

grails - 获取文件列表

design-patterns - Groovy 中@Delegate、@Mixin 和 Traits 的区别?

grails - 在groovy中显示名称而不是id

c++ - 使用模板和/或 constexpr 在编译时构建函数

java - 从 java 执行 groovy 脚本时如何阻止对某些类的访问?

C++ 模板元编程

c++ - 什么特征/概念可以保证 memsetting 一个对象是明确定义的?

python - 在 Python 中,如何响应对象上不存在的方法调用?

c++ - 替换模板上的虚函数