我知道在Groovy中,您可以使用字符串在类/对象上调用方法.例如:
Foo."get"(1)
/* or */
String meth = "get"
Foo."$meth"(1)
Run Code Online (Sandbox Code Playgroud)
有没有办法在课堂上这样做?我将类的名称作为字符串,并希望能够动态调用该类.例如,希望做类似的事情:
String clazz = "Foo"
"$clazz".get(1)
Run Code Online (Sandbox Code Playgroud)
我想我错过了一些非常明显的东西,但我无法弄明白.
cha*_*wit 29
正如Guillaume Laforge对Groovy ML的建议,
("Foo" as Class).get(i)
Run Code Online (Sandbox Code Playgroud)
会给出相同的结果.
我用这段代码测试过:
def name = "java.lang.Integer"
def s = ("$name" as Class).parseInt("10")
println s
Run Code Online (Sandbox Code Playgroud)
Aar*_*lla 16
试试这个:
def cl = Class.forName("org.package.Foo")
cl.get(1)
Run Code Online (Sandbox Code Playgroud)
稍微长一点,但应该工作.
如果你想为静态方法创建类似"switch"的代码,我建议实例化类(即使它们只有静态方法)并将实例保存在地图中.然后你可以使用
map[name].get(1)
Run Code Online (Sandbox Code Playgroud)
选择其中一个.
[编辑] "$name"是GString一个有效的声明."$name".foo()意思是"调用foo()类的方法GString.
[EDIT2]使用Web容器(如Grails)时,必须指定类加载器.有两种选择:
Class.forName("com.acme.MyClass", true, Thread.currentThread().contextClassLoader)
Run Code Online (Sandbox Code Playgroud)
要么
Class.forName("com.acme.MyClass", true, getClass().classLoader)
Run Code Online (Sandbox Code Playgroud)
第一个选项仅适用于Web上下文,第二个选项也适用于单元测试.这取决于您通常可以使用与调用的类相同的类加载器forName().
如果您遇到问题,请使用第一个选项并设置contextClassLoader单元测试:
def orig = Thread.currentThread().contextClassLoader
try {
Thread.currentThread().contextClassLoader = getClass().classLoader
... test ...
} finally {
Thread.currentThread().contextClassLoader = orig
}
Run Code Online (Sandbox Code Playgroud)