#java #object #dynamic
#java #объект #динамический
Вопрос:
Я реализовал код из этого руководстваhttp://www.javablogging.com/dynamic-in-memory-compilation/comment-page-1/#comment-65105 который в ореховой скорлупе динамически создает класс и только сохраняет его в памяти (по сравнению с записью в файл с расширением .java и компиляцией этого файла с расширением .class). В конце его main
он создает экземпляр класса с
Object instance = fileManager.getClassLoader(null)
.loadClass(fullName).newInstance();
System.out.println(instance);
И в создаваемом нами файле мы определили toString
метод, поэтому при распечатке instance
печатается имя класса. Но когда я добавляю методы в класс и пытаюсь вызвать их, я получаю сообщение об ошибке метод не определен для типа object.
Я знаю, что в обычных обстоятельствах мне нужно было бы использовать Object
like Object obj = new Foo();
, и тогда я мог бы вызвать члены Foo, но с кодом, который я показал выше, я не могу придерживаться new
перед fileManager...newInstance();
Заключение:
Как я могу создать экземпляр DynaClass (динамически создаваемого класса) из руководства и вызвать его члены.
Обновить:
Я не уверен, возможно ли привести объект, потому что мы создаем класс динамически, и все находится в строках. Насколько я знаю, вы не можете использовать что-либо со строковым именем.
Комментарии:
1. Просто приведите его (если можете).
2. @duffymo К чему вы его приводите, если тип еще не существует? (Или я неправильно понимаю цель здесь?)
3. Тип существует в памяти, но у нас нет имени для его приведения, поскольку имя находится в строке.
4. Вы пробовали
Foo foo = (Foo)instance;
? Если вы создаете класс во время выполнения из исходного кода, попробуйте библиотеки Javassist или Janino.5. Для приведения нет
Foo
. Я могу заглянуть в библиотеки, но мне нужно избегать библиотек и использовать чистую Java.
Ответ №1:
приведите его?
Foo instance= (Foo) FileManager.getClassLoader(null) .loadClass(полное имя).newInstance();
Редактировать
О, очевидно, вы создаете код класса в виде строки, поэтому во время компиляции не на что ссылаться…
Итак, вы ничего не можете сделать, кроме вызова методов через отражение, я полагаю?
Method method = instance.getClass().getMethod("myMethod", noparams);
method.invoke(instance, null);
Возможно, было бы лучше создать интерфейс с методами, которые вы хотите использовать, и ваш динамический класс реализует этот интерфейс. Затем вы можете привести свой объект к этому интерфейсу. Обычно так работают подключаемые модули.
Комментарии:
1. Если вы просмотрите руководство, вы увидите, что мы динамически создаем этот класс со строками, поэтому я не мог поместить объект string в приведение.
2. Отражение — единственный способ? Это кажется громоздким. Разве я не должен иметь экземпляр объекта и использовать его нормально?
3. Это сложно, но это потому, что Java на самом деле не предназначалась для этого.
4. Как насчет реализации интерфейса? (см. Мой обновленный ответ)
5. И в любом случае даже с кодом, который вы предоставили, используя отражение, все равно не позволит
getDeclaredMethod
использоваться наinstance
, потому что он считает, что егоObject