2013-07-17 1 views
4

В заводной это довольно легко создать укупорочное метод, например:Почему закрытие метода в объекте класса не выполняется?

groovy:000> p = 1.&plus 
===> [email protected] 
groovy:000> p(3) 
===> 4 

Однако, по какой-то причине происходит сбой при попытке использовать экземпляр Class:

groovy:000> List.isInstance([]) 
===> true 
groovy:000> t = List.&isInstance 
===> [email protected] 
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 
===> [email protected] 
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) 
     ... 

Это довольно легко работайте вокруг этого, но я хотел бы понять, почему это происходит. Есть ли что-то в СС, которое останавливает это от работы и т. Д.?

ответ

3

При использовании указатель метода на экземпляре Class то он должен явно использовать doCall() метод, предоставленный MethodClosure вместо использования по умолчанию call() из Closure.

doCall метод из MethodClosure переопределяет закупоривающего 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.

С другой стороны, &plus работает соответствующим образом, потому что указатель метода создается на POJO.