Я работаю над проектом, в котором есть много объектов, которые создаются библиотекой, и у меня нет доступа к процессу создания этих объектов.
Следующие примеры являются хорошим примером для иллюстрации моей проблемы.
код:
public class Clazz {
//The contents of Clazz are irrelevant
//Clazz is NOT my class. I have no access to its internal structure.
//However, I do have access to Clazz objects that were created elsewhere.
}
ExampleInterface
- это интерфейс, который Clazz может реализовать или не реализовать во время компиляции.
код:
public interface ExampleInterface {
public void run();
}
Следующий код - проблема, с которой я сталкиваюсь. Обратите внимание на следующее:
-
run()
вызывается только тогда, когда c является экземпляромExampleInterface
. -
getRunConditions(Clazz c)
иexecuteClazz(Clazz c)
являются частными методами в классе, к которому у меня нет доступа. - Во время компиляции
Clazz
не будет содержать метод с именемrun()
. - ExampleExecutor не мой класс. У меня нет доступа к нему ни в одном (я даже не могу получить экземпляр класса).
код:
public class ExampleExecutor {
public void executeClazz(Clazz c) {
if ((c instanceof ExampleInterface) && getRunConditions(c)) {
ExampleInterface ex = (ExampleInterface) c;
ex.run();
}
}
}
Очевидно, что следующий метод не является синтаксически возможным, но это то, чего я пытаюсь достичь. В принципе, если c не реализует ExampleInterface
, установите c для реализации ExampleInterface
, а затем предоставите методы, которые должны быть переопределены.
Обратите внимание на следующее:
-
extendInterface(
Name of Interface
)
является сильным синтаксисом . I созданный в попытке проиллюстрировать мою цель. -
run()
должен быть определен здесь (во время выполнения). - Я не могу использовать оболочку или прокси-класс в качестве решения. IE, объект
Clazz
должен завершить реализациюExampleInterface
, и я не могу использовать обходной путь. (обратитесь к этой ссылке, если вы хотите узнать почему).
код:
public void implementInterface(Clazz c) {
if (!(c instanceof ExampleInterface)) {
c.extendInterface(ExampleInterface {
@Override
public void run() {
//code
}
});
}
}
Чтобы прояснить, проблема, с которой я сталкиваюсь, заключается в том, что мне всегда нужно знать, когда run()
вызывается в Clazz
. Если Clazz
никогда не реализует ExampleInterface
, я не могу знать, когда следует вызывать run()
.
В то же время я также хотел бы иногда добавлять поддержку run()
, когда она по умолчанию не поддерживается. Поскольку у меня нет доступа к созданию объектов Clazz
, я не могу этого сделать, реализуя сам интерфейс.
Вопрос: Проще говоря, возможно ли реализовать интерфейс (и предоставить необходимые методы) во время выполнения?
ПРИМЕЧАНИЕ. Хотя единственное решение может потребовать отражения (и если да, то, пожалуйста, разместите его ниже), в библиотеке, которую я использую, есть менеджер безопасности, который блокирует использование всех отражений. IE, рефлексивное решение может быть полезным для других в будущем, но для меня это бесполезно.
Кроме того, я не имею в виду использование библиотеки в моей собственной программе. Выполнено уже запущенное хост-приложение (которое я использую для библиотеки), а затем запускает код, который я пишу для него. Если этому приложению не нравится какой-либо код, который я предоставляю (IE, конфликтует с его менеджером безопасности), код никогда не компилируется.
Зачем мне это нужно:
Это связано с библиотекой, которую я использую. Поскольку ExampleExecutor
- это метод, к которому у меня нет доступа, и я не могу контролировать создание Clazz, я не могу определить, когда выполняется run()
.
Причина, по которой мне нужно знать, когда выполняется run()
, является то, что в действительности run()
является обработчиком событий, который является частью библиотеки, которую я использую.
Например: mouseClicked(CustomMouseEvent evt)
может быть методом, который является частью интерфейса CustomMouseListener
. Иногда экземпляр Clazz
Я работаю с заботами, когда мышь нажата (и, следовательно, наследует CustomMouseListener
), а в других случаях это не так.
В отличие от экземпляра Clazz
, мне всегда все равно, если щелкнуть мышью, и всегда нужно, чтобы событие было запущено.
В действительности, ExampleInterface
будет фактически следующим:
public interface CustomMouseListener {
public void mouseClicked(CustomMouseEvent evt);
public void mousePressed(CustomMouseEvent evt);
public void mouseReleased(CustomMouseEvent evt);
//etc
}