Ответ 1
Вы можете использовать что-то вроде cglib для генерации кода на лету
В простой Java можно переопределить метод класса программно во время выполнения (или даже создать новый метод)?
Я хочу иметь возможность сделать это, даже если я не знать классы во время компиляции.
То, что я имею в виду, переопределив во время выполнения:
abstract class MyClass{
public void myMethod();
}
class Overrider extends MyClass{
@Override
public void myMethod(){}
}
class Injector{
public static void myMethod(){ // STATIC !!!
// do actual stuff
}
}
// some magic code goes here
Overrider altered = doMagic(
MyClass.class, Overrider.class, Injector.class);
Теперь этот вызов...
altered.myMethod();
... будет вызывать Injector.myMethod() вместо Overrider.myMethod().
Injector.myMethod() - статический, потому что после выполнения "магии" он вызывается из другого экземпляра класса (это Overrider), (поэтому мы не позволяем ему получать доступ к локальным полям).
Вы можете использовать что-то вроде cglib для генерации кода на лету
В java6 добавлена возможность преобразования любого уже загруженного класса. Взгляните на changes в пакете java.lang.instrument
Для интерфейсов есть java.lang.reflect.Proxy
.
Для классов вам понадобится библиотека сторонних разработчиков или напишите справедливый бит кода. Обычно динамическое создание классов таким образом - это создание mocks для тестирования.
Существует также API-интерфейс инструментария, который позволяет модифицировать классы. Вы также можете изменять классы с помощью специального загрузчика классов или только файлы классов на диске.
Я написал статью для java.net о том, как прозрачно добавлять инструкции журнала в класс, когда он загружается загрузчиком классов, используя java agent.
Он использует библиотеку Javassist для управления байтовым кодом, в том числе с использованием компилятора Javassist для генерации дополнительного байт-кода, который затем вставлен в соответствующее место, а затем результирующий класс предоставляется загрузчику классов.
Уточненная версия доступна с проектом slf4j
.
Если я правильно понял, основная проблема, которая вас беспокоит, заключается в том, как передать делегат статического метода (например, на С#) через метод интерфейса экземпляра.
Вы можете проверить эту статью: Программист Java Посмотрит на делегатов С#, в котором показано, как получить ссылку на ваш статический метод и вызовите его. Затем вы можете создать класс-оболочку, который принимает имя статического метода в своем конструкторе и реализует ваш базовый класс для вызова статического метода из метода экземпляра.