Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对Groovy MOP中的invokeMethod方法感到困惑_Groovy_Mop - Fatal编程技术网

对Groovy MOP中的invokeMethod方法感到困惑

对Groovy MOP中的invokeMethod方法感到困惑,groovy,mop,Groovy,Mop,首先看一下下面的Groovy代码: class Car { def check() { System.out.println "check called..." } def start() { System.out.println "start called..." } } Car.metaClass.invokeMethod = { String name, args -> System.out.print("Call to $name intercep

首先看一下下面的Groovy代码:

class Car {

    def check() { System.out.println "check called..." }

    def start() { System.out.println "start called..." }

}

Car.metaClass.invokeMethod = { String name, args ->

    System.out.print("Call to $name intercepted... ")

    if (name != 'check') {
        System.out.print("running filter... ")
        Car.metaClass.getMetaMethod('check').invoke(delegate, null)
    }

    def validMethod = Car.metaClass.getMetaMethod(name, args)
    if (validMethod != null) {
        validMethod.invoke(delegate, args)
    } else {
        Car.metaClass.invokeMissingMethod(delegate, name, args)
    }
}

car = new Car()
car.start()
输出为:

Call to start intercepted... running filter... check called...
start called...
根据Groovy方法调度机制,我认为应该直接调用Car中的start方法,而不是被Car元类中的invokeMethod拦截。为什么invokeMethod会拦截start方法?在对象上调用方法时,如何调用invokeMethod


如果您能给我一些关于Groovy方法调度机制(MOP)的详细解释,我将不胜感激。

简而言之,您没有使用标准的元类,因此您没有得到标准的Groovy MOP


Car.metaClass.invokeMethod={
将让Car拥有一个ExpandoMetaClass作为元类。这个元类使用您作为开放块提供的invokeMethod(就像您所做的那样)拦截调用。这与在类本身中定义invokeMethod有很大不同。

请您详细解释ExpandoMetaClass如何更改标准Groovy MOP?blackdragIt最好先问一个特定的问题,然后再回答这个问题。在genral EMC(ExpandoMetaClass)中其行为与普通的元类(MetaClassImpl)几乎相同,但它允许添加方法和属性,而标准元类则不允许。一个不同之处是修改后的EMC(例如,您添加了一个方法)无法再自动删除。至于为什么选择此语法来拦截呼叫…我真的无法回答。这是你必须问Graeme Rocher的问题。谢谢,@blackdrag