как расширить класс во время выполнения с помощью отражения

#java #reflection #extends

#java #отражение #расширяет

Вопрос:

Представьте, что у меня есть два класса A и B, B расширяет A, как

 class B extends A
{
  ....
}
  

Однако в моем случае класс A зашифрован и может быть загружен моим ClassLoader только во время выполнения (во время компиляции, A.class не может быть распознан как файл .class, поскольку он зашифрован). Это означает, что класс A не существует во время компиляции.

Мои вопросы:

  1. как можно написать код для класса B, поскольку некоторые методы переопределяют методы в классе A?
  2. как я могу указать, что класс B распространяется на класс A во время выполнения?

Ответ №1:

Вы не можете с помощью отражения. Но вы можете с помощью CGLIB и, возможно, javassist

Ответ №2:

Вы можете создать фиктивную копию A, в которой есть все методы, которые вы хотите переопределить, и скомпилировать и развернуть только B.

Если вы не знаете, какие методы вы хотите переопределить до выполнения, вам нужно будет сгенерировать код, используя либо API компилятора, однако библиотека, подобная Objectweb ASM, вероятно, будет намного проще. Я предпочитаю ASM, потому что он может легко генерировать код для генерации того, что вы хотите, из шаблона. т. Е. вам не нужно писать весь код самостоятельно.

Комментарии:

1. Привет, я думаю, «Вы можете создать фиктивную копию A, в которой есть все методы, которые вы хотите переопределить, а также скомпилировать и развернуть только B.» это простой и правильный способ. Но есть вопрос, который не ясен. Мы говорим, что у нас есть класс A, и я создаю фиктивную копию, класс dummy_A, во время компиляции, чтобы развернуть класс B. Затем во время выполнения, как заменить содержимое класса dummy_A содержимым класса A. Я чувствую, что это похоже на то, что мы создаем класс во время компиляции, но это всего лишь оболочка. Затем во время выполнения мы динамически изменяем класс. Как внести изменения? Спасибо.

2. Нет, вы создаете класс с именем «A» в том же пакете. Он имеет то же имя, пакет и методы, что и класс, который вы хотите расширить. Когда вы развертываете код, вы развертываете только B (не развертывайте фиктивный «A»), ваш загрузчик классов загрузит реальный A и ваш B. До тех пор, пока методы и т.д. вы используете то же самое, все это будет работать.

3. Привет, Питер, я вижу… Что ж, это блестящий

4. Привет, Питер, я вижу… Что ж, это блестящий способ. Спасибо за вашу любезную помощь. Еще один вопрос. Моя реальная ситуация такова, что мне нужно сначала создать файл jar, включающий класс A, в качестве стороннего компонента. Затем я разрабатываю класс B (расширяет класс A) с открытым исходным кодом. Ваш способ основан на развертывании файлов .class. Но в моей реальной ситуации класс B не может расширить класс A (в отдельной библиотеке JAR), потому что класс A зашифрован. Вот почему необходима оболочка класса A. Я делаю это для защиты кода класса A. Есть идеи? Спасибо за вашу дальнейшую помощь и предложения.

5. A может быть зашифрован, но для использования его необходимо расшифровать. Это означает, что во время выполнения он такой же, как любой другой класс, поэтому я не вижу проблемы.