2009-10-07 9 views
35

Supponendo che ho un oggetto someObj di tipo indeterminato, mi piacerebbe fare qualcosa di simile:In groovy, c'è un modo per verificare se un oggetto ha un determinato metodo?

def value = someObj.someMethod() 

Dove non c'è alcuna garanzia che 'someObj' implementa il metodo someMethod(), e se così non fosse, solo restituire null.

C'è qualcosa del genere in Groovy, o devo avvolgerlo in un'istruzione if con un controllo instanceof?

+0

Un modo potrebbe essere quello di interate '.properties' per http://stackoverflow.com/questions/2585992/how-to-get-all -property-names-of-a-groovy-class – MarkHu

risposta

57

Usa respondsTo

class Foo { 
    String prop 
    def bar() { "bar" } 
    def bar(String name) { "bar $name" } 
} 

def f = new Foo() 

// Does f have a no-arg bar method 
if (f.metaClass.respondsTo(f, "bar")) { 
    // do stuff 
} 
// Does f have a bar method that takes a String param 
if (f.metaClass.respondsTo(f, "bar", String)) { 
    // do stuff 
} 
4

si dovrebbe essere in grado di fare qualcosa di simile:

SomeObj.metaClass.getMetaMethod("someMethod") 

Oppure si può ripiegare al buon vecchio Java riflessione API.

+2

Non c'è nulla di buono nell'API di relection :) –

3

Basta implementare methodMissing nella classe:

class Foo { 
    def methodMissing(String name, args) { return null; } 
} 

E poi, ogni volta che si tenta di richiamare un metodo che non esiste, si otterrà un valore nullo.

def foo = new Foo(); 
assert foo.someMethod(), null 

Per ulteriori informazioni, date un'occhiata qui: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

+0

Ciò significa che tutti i suoi oggetti che non hanno il comportamento someMethod dovrebbero implementare il metodo? – Langali

2

È possibile raggiungere questo obiettivo utilizzando getMetaMethod insieme all'operatore navigazione sicura ?.:

def str = "foo" 
def num = 42 

def methodName = "length" 
def args = [] as Object[] 

assert 3 == str.metaClass.getMetaMethod(methodName, args)?.invoke(str, args); 
assert null == num.metaClass.getMetaMethod(methodName, args)?.invoke(num, args); 
2

se la classe:

MyClass.metaClass.methods*.name.any{it=='myMethod'}//true if exist 

se oggetto:

myObj.class.metaClass.methods*.name.any{it=='myMethod'}//true if exist 
Problemi correlati