代码之家  ›  专栏  ›  技术社区  ›  John Wagenleitner

动态调用静态方法的Groovy方法

  •  26
  • John Wagenleitner  · 技术社区  · 16 年前

    我知道在Groovy中,可以使用字符串调用类/对象上的方法。例如:

    Foo."get"(1)
      /* or */
    String meth = "get"
    Foo."$meth"(1)
    

    String clazz = "Foo"
    "$clazz".get(1)
    

    我想我错过了一些非常明显的东西,只是我无法理解。

    6 回复  |  直到 11 年前
        1
  •  29
  •   chanwit    16 年前

    正如Guillaume Laforge对Groovy ML的建议,

    ("Foo" as Class).get(i)
    

    将给出相同的结果。

    我已经使用以下代码进行了测试:

    def name = "java.lang.Integer"
    def s = ("$name" as Class).parseInt("10")
    println s
    
        2
  •  17
  •   Aaron Digulla    12 年前

    def cl = Class.forName("org.package.Foo")
    cl.get(1)
    

    稍微长一点,但应该可以。

    map[name].get(1)
    

    选择其中一个。

    "$name" 是一个 GString 因此,这是一个有效的声明。 "$name".foo() 表示“调用方法” foo() 班上的 GString .

    [编辑二]

    Class.forName("com.acme.MyClass", true, Thread.currentThread().contextClassLoader)
    

    Class.forName("com.acme.MyClass", true, getClass().classLoader)
    

    forName() .

    contextClassLoader 在单元测试中:

    def orig = Thread.currentThread().contextClassLoader
    try {
        Thread.currentThread().contextClassLoader = getClass().classLoader
    
        ... test ...
    } finally {
        Thread.currentThread().contextClassLoader = orig
    }
    
        3
  •  3
  •   Paul King    14 年前

    对Chanwit答案的补充,说明了实例的创建:

    def dateClass = 'java.util.Date' as Class
    def date = dateClass.newInstance()
    println date
    
        4
  •  2
  •   ken    14 年前

    import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
    
    def target = application.domainClasses.find{it.name == 'ClassName'}
    target.clazz.invokeMethod("Method",args)
    

        5
  •  1
  •   Kirk Woll    14 年前

    // define in script (not object) scope  
    def loader = this.getClass().getClassLoader()
    
    // place this in some MetaUtils class, invoked on app startup  
    String.metaClass.toClass = {  
        def classPath = getPath(delegate) // your method logic to determine 'path.to.class'
        Class.forName(classPath, true, this.loader)  
    }
    
    // then, anywhere in your app  
    "Foo".toClass().bar()
    

    String.metaClass.toObject = {  
        def classPath = getPath(delegate)  
        Class.forName(classPath, true, this.loader).newInstance()  
    }
    

    Groovy是纯粹的乐趣;--)

        6
  •  1
  •   alcoholiday    12 年前

    Import my.Foo
    def myFx="myMethodToCall"
    def myArg = 12
    
    Foo."$myFx"(myArg)
    

    按预期和所需调用Foo.myMethodToCall(12)。但我不知道情况是否一直如此。