2009-10-07 17 views
35

Suponiendo que tengo un objeto someObj de tipo indeterminado, me gustaría hacer algo como:En groovy, ¿hay alguna forma de comprobar si un objeto tiene un método determinado?

def value = someObj.someMethod() 

Donde no hay garantía de que 'someObj' implementa el método someMethod(), y si no lo hace, simplemente return null.

¿Hay algo así en Groovy, o debo envolverlo en un enunciado if con un cheque instanceof?

+0

Una forma sería a Interate '.properties' por http://stackoverflow.com/questions/2585992/how-to-get-all -property-names-of-a-groovy-class – MarkHu

Respuesta

57

Uso 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

usted debería ser capaz de hacer algo como:

SomeObj.metaClass.getMetaMethod("someMethod") 

o puede caer de nuevo a la API buena reflexión de edad Java.

+2

No hay nada bueno acerca de la relection API :) –

3

Sólo aplicar methodMissing en su clase:

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

Y entonces, cada vez que se intenta invocar un método que no existe, se obtendrá un valor nulo.

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

Para obtener más información, echa un vistazo aquí: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

+0

Eso significa que todos sus objetos que no tienen el comportamiento de algún método tendrían que implementar el método? – Langali

2

Esto se puede conseguir mediante el uso de getMetaMethod junto con el operador de navegación segura ?.:

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

si la clase:

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

si el objeto:

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