2012-01-03 3 views
11

Во время выполнения я хватаю список имен методов в классе, и я хочу вызвать эти методы. Я понимаю, как получить первую часть сделано здесь: http://docs.codehaus.org/display/GROOVY/JN3535-ReflectionКак динамически вызывать методы в Groovy?

GroovyObject.methods.each{ println it.name } 

То, что я не могу найти информацию о том, как затем вызвать метод, как только я схватил его имя.

То, что я хочу, чтобы получить здесь:

GroovyObject.methods.each{ GroovyObject.invokeMethod(it.name, argList) } 

Я не могу найти правильный синтаксис. Вышеприведенное, кажется, предполагает, что я перегрузил метод invokeMethod по умолчанию для класса GroovyObject, который НЕ является тем направлением, в котором я хочу идти.

ответ

14

Groovy позволяет для динамического вызова метода, а также динамических аргументов, используя оператор распространения:

def dynamicArgs = [1,2] 
def groovy = new GroovyObject() 
GroovyObject.methods.each{ 
    groovy."$it.name"(staticArg, *dynamicArgs) 
} 

Reference here

Вопрос ответил here.

+1

Хотя это теоретически может ответить на вопрос, [было бы предпочтительнее] (http://meta.stackexchange.com/ q/8259), чтобы включить здесь основные части ответа и предоставить ссылку для справки. –

+0

Предоставленная ссылка мертва. Связана ли эта ссылка? http://www.groovy-lang.org/metaprogramming.html#_dynamic_method_names – chrish

+0

Я обновил ссылку, чтобы указать на заархивированную версию оригинальной, теперь мертвой ссылки. Счастливое метапрограммирование! – avgvstvs

16

Как только вы получите объект MetaMethod из метакласса, вы можете позвонить ему invoke. Например:

class MyClass { 
    def myField = 'foo' 
    def myMethod(myArg) { println "$myField $myArg" } 
} 
test = new MyClass() 
test.metaClass.methods.each { method -> 
    if (method.name == 'myMethod') { 
     method.invoke(test, 'bar') 
    } 
} 

В качестве альтернативы, вы можете использовать имя непосредственно:

methodName = 'myMethod' 
test."$methodName"('bar') 
+1

Есть ли способ проверить, существует ли метод без итерации над 'metaClass.methods'? –

+1

@AlexanderSuraphel ['responsesTo()') (http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Object.html#respondsTo (java.lang.String)) метод скажет вам, существует ли метод. Пример: 'if (test.respondsTo (methodName)) {...}' – ataylor