从String动态实例化类的Groovy方法

时间:2011-10-13 18:02:04

标签: groovy

this question about the Groovy way to dynamically invoke a static method的答案非常有用,但我遇到以下情况时遇到问题:

我定义了一个简单的Groovy类:

class Item {
  def id = 1
  def data = [ "a", "b" ]
}

然后我定义了一个想要动态加载Item类的简单实用程序类:

class Util {
  static def main(args) {
     def cls = "Item" as Class
     def instance = cls.newInstance()
     println instance.toString()
  }
}

Util.groovy与Item.groovy位于同一个文件夹中

当我尝试运行Util.groovy时,我收到以下错误:

Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: 
Cannot cast object 'Item' with class 'java.lang.String' 
to class 'java.lang.Class' due to: 
java.lang.ClassNotFoundException: Item
        at Util.main(Util.groovy:3)

我能使它工作的唯一方法是使用groovyc来预编译Item.groovy,但这忽略了作为Groovy的观点:)

2 个答案:

答案 0 :(得分:32)

这可以使用underlying GroovyClassLoader

def instance = this.class.classLoader.loadClass( 'Item', true, false )?.newInstance()

答案 1 :(得分:6)

我必须这样做并找到一种有趣的方式 - 所以我想我会回来提起它。

我有一个问题,因为我想将值传递给newInstance(使用非默认构造函数)并且所有解决方案似乎都有点工作(我很懒,好吗?)

无论如何,假设您要创建一个新的Integer(5)...试试这个:

c = "java.lang.Integer"
p = "5"
def result = Eval.me("return new ${c}(${p})")
assert(result == 5)

工作得很好虽然我确信这是最慢的解决方案。具有该方法适用于许多其他情况的优点。