Внедрить новые методы и свойства в классы во время выполнения - PullRequest
7 голосов
/ 14 сентября 2009

Есть ли способ, которым мы можем внедрить новые методы и свойства в классы во время выполнения.

http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html утверждает, что мы можем сделать это с помощью Groovy.

Возможно ли это просто с помощью Java?

Ответы [ 5 ]

10 голосов
/ 14 сентября 2009

Это возможно, просто используя Java

Простой ответ - решительное «Вы не хотите этого делать!».

Это технически возможно, но не без использования чрезвычайно сложных, дорогих и хрупких приемов, таких как модификация байт-кода 1 . И даже тогда вы должны полагаться на динамическую загрузку для доступа к измененному типу и (возможно) к отражению, чтобы использовать его новые члены. Короче говоря, вы будете причинять себе много боли, а если и не выиграете, тем меньше.

Java является языком статической типизации, и добавление / изменение сигнатур типов классов может нарушить контракт статической типизации класса.


1 - AspectJ и т. П. Позволяют вводить в класс дополнительное поведение, но, вероятно, это не «внедрение во время выполнения», которое вам нужно. Конечно, внедренные методы не будут доступны для вызова статически скомпилированного кода.

1 голос
/ 14 сентября 2009

Вы можете делать довольно забавные вещи с помощью AOP, хотя подлинная модификация классов во время выполнения - довольно сложная техника, требующая много магии загрузки классов и ловкости рук.

Что проще, так это использование методов AOP для генерации подкласса вашего целевого класса и введения в него новых методов, которые AOP называют «mixin» или «внедрение». См. здесь , чтобы прочитать, как это делает Spring AOP, хотя это может быть довольно неудачно по сравнению с тем, чего вы на самом деле пытаетесь достичь.

1 голос
/ 14 сентября 2009

Возможно ли это просто с помощью Java?

Именно так, «единственное», что вам нужно сделать, это определить инструментальный агент , который поставляет соответствующий ClassFileTransformer, и вам придется использовать отражение для вызова добавленные методы. Скорее всего, это не то, что вы хотите сделать, но это выполнимо и есть четко определенный интерфейс для этого. Если вы хотите изменить существующие методы, вас может заинтересовать что-то вроде AspectJ .

1 голос
/ 14 сентября 2009

Так что, если бы вы были действительно сумасшедшими, вы могли бы сделать что-то вроде того, что они обозначили здесь Что вы можете сделать, это загрузить файл .java, найти правильную точку вставки, добавить все необходимые методы, вызвать компилятор java и перезагрузить класс. Удачи в устранении этого беспорядка:)

Редактировать Это на самом деле может быть полезным ...

0 голосов
/ 14 сентября 2009

Хотя это возможно, но это бесполезно.

Как бы вы получили доступ к этим новым полям и методам?

Вы не можете использовать эти методы и поля напрямую (как «обычные» поля и методы), так как они не будут компилироваться в.

Если все, что вам нужно, это возможность добавить «свойства» и «методы», вы можете использовать Map<String, Object> для «динамических свойств» и Map<String, SuitableInterface> для «динамических методов» и искать их по имени.

Если вам нужен язык расширения для Java, можно добавить встроенный динамический язык (например, Javascript или Groovy); большинство из них могут обращаться к произвольным объектам и методам Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...