为什么Class对象的方法闭包失败?

时间:2013-07-17 02:12:51

标签: groovy closures

在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中是否存在阻止其工作的内容?

1 个答案:

答案 0 :(得分:3)

当您在Class的实例上使用方法指针时,它必须明确使用doCall()提供的MethodClosure方法,而不是使用call()的{​​{1}}方法1}}。

来自Closure

doCall方法会覆盖Closure的MethodClosure,并使用doCall拦截方法调用,而不是从invokeMethod调用call()。< / p>

Closure如果您明确使用与MethodClosure中的InvokerHelperdoCall列表同义的MethodClosure,也会有效。

metaClass
如果对象是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 的实例,则使用MOP的

invokeStaticMethod

另一方面,Class正常工作,因为在POJO上创建了方法指针。