Groovy方式动态调用静态方法 [英] Groovy way to dynamically invoke a static method
问题描述
我知道在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 $ c
$ 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屋!