4

在 groovy 中,创建方法闭包非常容易,例如:

groovy:000> p = 1.&plus
===> org.codehaus.groovy.runtime.MethodClosure@a7981d5
groovy:000> p(3)
===> 4

但是,由于某种原因,它在尝试使用以下实例时失败Class

groovy:000> List.isInstance([])
===> true
groovy:000> t = List.&isInstance
===> org.codehaus.groovy.runtime.MethodClosure@31ca1a68
groovy:000> t([])
ERROR groovy.lang.MissingMethodException:
No signature of method: java.util.List.isInstance() is applicable for argument types: (java.util.ArrayList) values: [[]]
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...
groovy:000> t = List.class.&isInstance
===> org.codehaus.groovy.runtime.MethodClosure@7b34c5ff
groovy:000> t([])
ERROR groovy.lang.MissingMethodException:
No signature of method: java.util.List.isInstance() is applicable for argument types: (java.util.ArrayList) values: [[]]
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

解决这个问题很容易,但我想了解为什么会发生这种情况。MOP 中有什么东西可以阻止它工作等吗?

4

1 回答 1

3

当您在实例上使用方法指针时,Class它必须显式使用doCall()提供的方法,MethodClosure而不是使用默认call()Closure.

doCall方法 fromMethodClosure覆盖闭包并通过 using而不是调用fromdoCall来拦截方法调用。invokeMethodcall()Closure

MethodClosure如果您明确使用与in或ListInvokerHelper同义的 which,也可以使用。doCallMethodClosuremetaClass

import org.codehaus.groovy.runtime.InvokerHelper

t = List.&isInstance

assert t.owner.simpleName == 'List'
assert t.doCall([]) == true    
assert InvokerHelper.getMetaClass(t.owner).
              invokeStaticMethod(t.owner, 'isInstance', []) == true
assert List.metaClass.invokeStaticMethod(t.owner, 'isInstance', []) == true

如果对象是Class.

另一方面,&plus因为方法指针是在 POJO 上创建的,所以可以正常工作。

于 2013-07-17T04:19:43.777 回答