Подтвердить что ты не робот

Groovy способ динамического создания экземпляра класса из String

Ответ Этот вопрос о способе 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:)

4b9b3361

Ответ 1

Это работает, используя базовый GroovyClassLoader:

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

Ответ 2

Мне просто нужно было сделать это и найти интересный способ - так что я думал, что вернусь и упомянул об этом.

У меня была проблема с этим, потому что я хотел передать значение newInstance (использовать конструктор не по умолчанию), и все решения, казалось, были немного полезными (я ленив, ладно?)

В любом случае, предположим, что вы хотите создать новый Integer (5)... попробуйте следующее:

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

Работал очень хорошо, хотя я уверен, что это самое медленное решение. Имеет то преимущество, что метод применим ко многим другим ситуациям.