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

标签 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 中有什么东西可以阻止它工作等吗?

最佳答案

当您在 Class 的实例上使用方法指针时那么它必须明确地使用 doCall() MethodClosure提供的方法而不是使用默认的 call()Closure .
doCall来自 MethodClosure 的方法覆盖 Closure 的 doCall并使用 invokeMethod 拦截方法调用而不是调用 call()来自 Closure .
MethodClosure如果您明确使用 InvokerHelper 也可以使用与 doCall 同义在 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

invokeStaticMethod如果对象是 Class 的实例,则使用 MOP 的.

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

关于groovy - 为什么 Class 对象的方法闭包会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17689958/

相关文章:

grails - 无法保存域类实例;获取类型不匹配错误

hibernate - 在 Grails 中使用条件对多个字段进行排序

Jenkins 管道 : How to write UTF-8 files with writeFile?

javascript - 闭包在类方法上的工作方式是否相同?

javascript - 为什么clearInterval 在我的脚本中不起作用?

regex - Groovy 正则表达式模式匹配中是否存在命名组?

testing - Groovy:将 spock 测试文件与程序文件分开

c# - 有没有办法让 C# 不提示实际上没有未初始化的未初始化变量?

javascript - 我可以使用 y-combinator 来获取这个闭包的对象引用吗?

javascript - 使用 Function() 构造函数作为闭包