Reputation: 3389
Given the following groovy class:
class A {
static x = { }
}
How do I check if class A has defined a static property called 'x'? Neither option below seems to work:
A.hasProperty('x')
A.metaClass.hasProperty('x')
Upvotes: 6
Views: 6580
Reputation: 4096
Look at GrailsClassUtils.getStaticFieldValue - it returns a static field value by name, null if no property exist or not set. You may look at implementation if that's helpful
Upvotes: 4
Reputation: 2488
As of 2017 and groovy 2.4.x, the best way to check appears to be this:
A.metaClass.getMetaProperty('x') != null
It works for both static and non-static properties as well as for properties defined with only getter and setter (but no actual field), or by a field without a getter or setter (e.g. in a java class). You can inspect returned MetaProperty for more details if required. Beware that a property might be defined by a setter only thus being not readable. So, if it is important, adjust your checks accordingly.
Note however that this method does not allow to check whether property is static.
sudhir answer is probably second best, as it's implementation relies on getDeclaredFields and as a result, does not find properties defined only by getter and setter. It also only useful if you're using grails. It also fetches the actual value if present which may or may not be desired.
SteveD answers does not work. Yet can be fixed by removing 'class' before declaredFields and adding checks for getters and setters. So, full check for property existence is as follows:
def hasProperty = { Class c, String propertyName ->
if (!propertyName)
return false;
String p2 = propertyName.substring(0, 1).toUpperCase()
if (propertyName.length()> 1)
p2 += propertyName.substring(1)
return c.declaredFields.find {
it.name == propertyName /* && isStatic(it.modifiers) */
} || c.declaredMethods.find {
it.name == ('get' + p2) /* && isStatic(it.modifiers) */
} || c.declaredMethods.find {
it.name == ('is' + p2) /* && isStatic(it.modifiers) */
} || c.declaredMethods.find {
it.name == ('set' + p2)/* && isStatic(it.modifiers) */
}
}
Note that this method also checks that property is actually static (just import static java.lang.reflect.Modifier.isStatic and uncomment isStatic checks). Same as above, beware of setter-only properties.
Upvotes: 0
Reputation: 4126
A.metaClass.hasProperty(A,'x')
or
A.metaClass.respondsTo(A,'getX')
Upvotes: 3
Reputation: 5405
I couldn't see a groovier way of doing this other than using Java's reflection API:
import static java.lang.reflect.Modifier.isStatic
class A {
static x = 1
}
def result = A.class.declaredFields.find {
it.name == 'x' && isStatic(it.modifiers)
}
println result == null ? 'class does not contain static X' :
'class contains static X'
Upvotes: 6
Reputation: 187499
I couldn't see any obvious way to check for a static property directly, but checking for a static method named getProperty
is equivalent (I think)
def getStaticProperty(String name, Class clazz) {
def noArgs = [].toArray()
def methodName = 'get' + name[0].toUpperCase()
if (name.size() > 1) {
methodName += name[1..-1]
}
clazz.metaClass.getStaticMetaMethod(methodName, noArgs)
}
// class that will be used in tests
class Foo {
static String x = 'bar'
static Integer num = 3
}
// tests
assert getStaticProperty('x', Foo)
assert getStaticProperty('num', Foo)
assert getStaticProperty('noSuchProperty', Foo) == null
Upvotes: 0