简体   繁体   中英

Groovy way to dynamically instantiate a class from String

The answers of this question about the Groovy way to dynamically invoke a static method were very helpful but I'm having trouble with the following case:

I defined a simple Groovy class:

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

I then defined a simple utility class that wants to dynamically load the Item class:

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

Util.groovy is in the same folder as Item.groovy

When I try to run Util.groovy I get the following error:

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)

The only way that I could make it work was by using groovyc to precompile Item.groovy, but this misses the point of being Groovy :)

这可以使用底层的GroovyClassLoader

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

I just had to do this and found an interesting way--so I thought I'd come back and mention it.

I had A problem with this because I wanted to pass a value to newInstance (use a non-default constructor) and all the solutions seemed to be a little bit of work (I'm lazy, okay?)

Anyway, suppose you want to create a new Integer(5)... try this:

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

Worked really well although I'm sure it's about the slowest solution possible. Has the advantage that the method is applicable to many other situations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM