Отражение: взять значения из неизвестного работающего приложения - PullRequest
1 голос
/ 23 декабря 2010

Я пишу приложение, которое ищет типы семафоров в полях неизвестных классов в неизвестном приложении (передано пользователем). Я сделал это с помощью Reflection, и это сработало.

Теперь я хочу заполнить эти семафоры значениями, взяв их из запущенного экземпляра этого неизвестного приложения. Поэтому я взял класс с «основным» методом этого неизвестного приложения, создал newInstance и передал его при вызове метода main для запуска приложения:

Class mainClass = getItSomeWhere();
Object instance = mainClass.newInstance();
Method mainMethod = mainClass.getDeclaredMethod("main", new Class[]{String[].class});
mainMethod.invoke(instance, new Object[]{args});

и все работало нормально.

Теперь, как я могу получить значения семафоров, взяв их из классов этого запущенного приложения, когда у меня есть только экземпляр основного класса?

Большое спасибо за ответы.

Ответы [ 2 ]

0 голосов
/ 23 декабря 2010

@ AlexR:

Я знаю, что это немного несовместимо, я попытаюсь объяснить:

Если основной класс приложения сделан так:

public class MainClass{

       public static void main(String [] args){
                    new Gui();
       }
}

и вы запускаете метод main с помощью Reflection, вы не можете взять значения полей Gui, а также экземпляры классов, которые есть в Gui и т. Д.

Вы понимаете проблему?


РЕДАКТИРОВАТЬ: AlexR, спасибо, что сообщили мне BCEL из Джакарты, это помогло мне решить проблему!

Узнав, как его использовать, я отредактировал все файлы классов приложений, где есть new Semaphore();, и я заменил ее расширенным классом Semaphore, сделанным на заказ, который позволяет мне получить значение, передав его объекту-наблюдателю!

Большое спасибо и счастливого нового года!

0 голосов
/ 23 декабря 2010

Хорошо, семафор - это просто класс, как и все другие классы. Если вы имеете в виду экземпляры уровня класса типа семафор, это просто (точно так же, как вы имеете дело с переменными уровня класса других типов):

Class clazz = ...
for (Field f : clazz.getDeclaredFields()) {
    if (f.getType().equals(Semaphore.class)) {
       // do what you want here.
    }
}

Но если вы хотите иметь дело с переменными, определенными в методах, вы должны использовать одну из библиотек байтового кода (например, BCL из Джакарты).

Кстати, вам действительно не следует создавать экземпляр класса, который содержит ваш основной метод:

  • вы не знаете, какой конструктор вызывать и с какими параметрами.
  • Класс может быть абстрактным, поэтому его нельзя создать вообще.
...