【问题标题】:How do I check if a groovy class has a static property?如何检查 groovy 类是否具有静态属性?
【发布时间】:2012-01-04 10:06:48
【问题描述】:

给定以下 groovy 类:

​class A {
    static x = { }
}

如何检查 A 类是否定义了一个名为“x”的静态属性? 以下选项似乎都不起作用:

A.hasProperty('x')
A.metaClass.hasProperty('x')

【问题讨论】:

    标签: groovy


    【解决方案1】:

    除了使用 Java 的反射 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'
    

    【讨论】:

    • 静态 (Java) 字段是否与静态 (Groovy) 属性相同?
    【解决方案2】:

    查看GrailsClassUtils.getStaticFieldValue - 它按名称返回静态字段值,如果不存在或未设置属性,则返回 null。如果有帮助,您可以查看实现

    【讨论】:

    • 很遗憾,该链接不再有效。网络 404 错误。
    • 即使链接失效,你仍然可以使用GrailsClassUtils
    【解决方案3】:
    A.metaClass.hasProperty(A,'x')
    

    A.metaClass.respondsTo(A,'getX')
    

    【讨论】:

      【解决方案4】:

      我看不到任何直接检查静态属性的明显方法,但检查名为 getProperty 的静态方法是等效的(我认为)

      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
      

      【讨论】:

        【解决方案5】:

        截至 2017 年和 groovy 2.4.x,最好的检查方法似乎是这样的:

        A.metaClass.getMetaProperty('x') != null
        

        它适用于静态和非静态属性以及仅使用 getter 和 setter(但没有实际字段)定义的属性,或者由没有 getter 或 setter 的字段定义的属性(例如在 java 类中)。如果需要,您可以检查返回的 MetaProperty 以获取更多详细信息。请注意,属性可能仅由 setter 定义,因此不可读。因此,如果它很重要,请相应地调整您的检查。

        但请注意,此方法不允许检查属性是否为静态。

        sudhir 的答案可能是第二好的,因为它的实现依赖于 getDeclaredFields,因此找不到仅由 getter 和 setter 定义的属性。它也仅在您使用 grails 时才有用。它还会获取可能需要也可能不需要的实际值。

        SteveD 的答案不起作用。然而,可以通过在声明字段之前删除“类”并添加对 getter 和 setter 的检查来修复。 因此,对属性存在的全面检查如下:

        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) */
            }
        }
        

        请注意,此方法还检查属性实际上是静态的(只需导入静态 java.lang.reflect.Modifier.isStatic 并取消注释 isStatic 检查)。与上面相同,请注意仅设置器的属性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-30
          • 1970-01-01
          • 2022-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-13
          • 1970-01-01
          相关资源
          最近更新 更多