2009-10-07 12 views
35

Unter der Annahme, dass ich ein Objekt someObj unbestimmter Art, würde Ich mag, wie etwas zu tun ist:In groovy, gibt es eine Möglichkeit zu überprüfen, ob ein Objekt eine bestimmte Methode hat?

def value = someObj.someMethod() 

Wo es keine Garantie gibt, dass ‚someObj‘ implementiert die someMethod() Methode, und wenn dies nicht der Fall, nur zurückgeben null.

Gibt es so etwas in Groovy, oder muss ich das in eine if-Anweisung mit einer instanceof Prüfung einbinden?

+0

Ein Weg, um zu Interate wäre '.properties' pro http://stackoverflow.com/questions/2585992/how-to-get-all -property-names-of-a-groovy-class – MarkHu

Antwort

57

Verwenden 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

sollten Sie in der Lage sein, etwas zu tun:

SomeObj.metaClass.getMetaMethod("someMethod") 

Oder Sie können zurück in die gute alte Java Reflection-API fallen.

+2

Es gibt nichts Gutes über die Reelection-API :) –

3

Nur methodMissing in Ihrer Klasse implementieren:

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

Und dann jedes Mal versuchen, eine Methode aufzurufen, die nicht existiert, werden Sie einen Nullwert erhalten.

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

Für weitere Informationen, werfen Sie einen Blick hier: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

+0

Das bedeutet, alle seine Objekte, die nicht das someMethod-Verhalten haben, müssten die Methode implementieren? – Langali

2

Sie können dies erreichen, indem getMetaMethod zusammen mit dem sicheren Navigation Operator ?.:

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

, wenn Klasse:

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

wenn Objekt:

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