Groovy方式动态调用静态方法 [英] Groovy way to dynamically invoke a static method

查看:891
本文介绍了Groovy方式动态调用静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Foo。get(1)
/ *或* /
字符串方式=get
Foo。$ meth(1)

有没有办法跟班上做这个?我把这个类的名字看作一个字符串,并希望能够动态地调用这个类。例如,您可以执行以下操作:

  String clazz =Foo
$ clazz.get 1)

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

解决方案

试试这个:

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


$
$ b

如果你想为静态方法创建类似switch的代码,我建议实例化这些类(即使它们只有静态方法)并将实例保存在地图中。您可以使用

  map [name] .get(1)

选择其中一个。



$ name是一个 GString 并且是这样一个有效的语句。 $ name.foo()表示调用类的方法 foo() > GString



使用Web容器(如Grails)时,必须指定classloader有两个选项:

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

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

第一个选项只能在Web上下文中使用,第二个方法也适用于单元测试,这取决于您通常可以使用与调用的类相同的类加载器, forName()



如果您遇到问题,请使用第一个选项并设置 contextClassLoader $ b $ pre $ def $ orig $ Thread.currentThread()。contextClassLoader
try {
Thread.currentThread()。contextCl assLoader = getClass()。classLoader

... test ...
} finally {
Thread.currentThread()。contextClassLoader = orig
}


I know in Groovy you can invoke a method on a class/object using a string. For example:

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

Is there a way to do this with the class? I have the name of the class as a string and would like to be able to dynamically invoke that class. For example, looking to do something like:

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

I think I'm missing something really obvious, just am not able to figure it out.

解决方案

Try this:

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

A little bit longer but should work.

If you want to create "switch"-like code for static methods, I suggest to instantiate the classes (even if they have only static methods) and save the instances in a map. You can then use

map[name].get(1)

to select one of them.

[EDIT] "$name" is a GString and as such a valid statement. "$name".foo() means "call the method foo() of the class GString.

[EDIT2] When using a web container (like Grails), you have to specify the classloader. There are two options:

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

or

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

The first option will work only in a web context, the second approach also works for unit tests. It depends on the fact that you can usually use the same classloader as the class which invokes forName().

If you have problems, then use the first option and set the contextClassLoader in your unit test:

def orig = Thread.currentThread().contextClassLoader
try {
    Thread.currentThread().contextClassLoader = getClass().classLoader

    ... test ...
} finally {
    Thread.currentThread().contextClassLoader = orig
}

这篇关于Groovy方式动态调用静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆