我正在开发一个项目,其中有很多由库创建的对象,并且我无法访问这些对象的创建过程。
以下片段是说明我的问题的一个很好的例子。
Code:
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 在编译时可能实现也可能不实现的接口。
Code:
public interface ExampleInterface {
public void run();
}
以下代码是我遇到的问题。请注意以下事项:
-
run()
仅当 c 是以下实例时才被调用ExampleInterface
.
-
getRunConditions(Clazz c)
and executeClazz(Clazz c)
都是我无权访问的类中的私有方法。
- 在编译时,
Clazz
will not包含一个名为run()
.
- 示例执行者是not我的课。我无法以任何方式访问它
方式(我什至无法获得该类的实例)。
Code:
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
)
is 编造的语法我
创建是为了说明我的目标。
-
run()
must在这里定义(在运行时)。
- 我无法使用包装器或代理类作为解决方案。 IE,
Clazz
对象必须最终实现ExampleInterface
,而且我无法使用解决方法。 (参考这个链接 https://stackoverflow.com/questions/23767885/how-to-check-when-a-method-is-run-in-another-class-in-java-method-call-listener如果你想知道为什么)。
Code:
public void implementInterface(Clazz c) {
if (!(c instanceof ExampleInterface)) {
c.extendInterface(ExampleInterface {
@Override
public void run() {
//code
}
});
}
}
澄清一下,我遇到的问题是我需要always知道什么时候run()
被叫进Clazz
. If Clazz
从来没有实施ExampleInterface
,我不知道什么时候run()
应该被称为。
同时,我也想偶尔添加对run()
当默认情况下不支持时。因为我无权访问创建Clazz
对象,我无法通过自己实现接口来做到这一点。
问题:简单地说,是否可以在运行时实现接口(并提供所需的方法)?
NOTE:虽然唯一的解决方案可能需要反射(如果是这样,请将其发布在下面),但我正在使用的库有一个安全管理器,可以阻止所有反射的使用。 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
}