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

发布于 2024-12-10 00:45:02 字数 887 浏览 1 评论 0原文

这个关于 Groovy 方式动态调用静态方法的问题的答案 非常有帮助,但我遇到了以下情况的麻烦:

我定义了一个简单的 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 的意义:)

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 :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静水深流 2024-12-17 00:45:02

这是有效的,使用 底层 GroovyClassLoader

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

This works, using the underlying GroovyClassLoader:

def instance = this.class.classLoader.loadClass( 'Item', true, false )?.newInstance()
救赎№ 2024-12-17 00:45:02

我只是必须这样做并找到了一种有趣的方法 - 所以我想我应该回来提及它。

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

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

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

效果非常好,尽管我确信这是最慢的解决方案。该方法的优点是适用于许多其他情况。

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.

如此安好 2024-12-17 00:45:02

使用 Java 中的 Class.forName() 的另一个选项(https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#forName(java.lang.String))

Groovy 中的示例工作代码:

class Dog {

   def bark()
   {
      println 'woof'
   }
}


def name = 'Dog'

def ins = Class.forName(name).newInstance()

ins.bark() // woof

Another option using Class.forName() from Java (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#forName(java.lang.String))

Example working code in Groovy:

class Dog {

   def bark()
   {
      println 'woof'
   }
}


def name = 'Dog'

def ins = Class.forName(name).newInstance()

ins.bark() // woof
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文