Экземпляр класса Java из типа Object может вызывать только методы типа Object

#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