我正在一个项目中,该项目有很多由库创建的对象,并且无法访问这些对象的创建过程。
以下代码片段很好地说明了我的问题。
码:
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()
。码:
public class ExampleExecutor {
public void executeClazz(Clazz c) {
if ((c instanceof ExampleInterface) && getRunConditions(c)) {
ExampleInterface ex = (ExampleInterface) c;
ex.run();
}
}
}
显然 ,以下方法在语法上不可行
,但这是我正在尝试实现的方法。基本上,如果c尚未实现ExampleInterface
,请将c设置为Implement
ExampleInterface
,然后提供必须重写的方法。
请注意以下几点:
extendInterface(
Name of Interface
)
是我为了说明我的目标而创建 的组合语法 。run()
必须 在运行时在这里定义。Clazz
对象必须最终实现ExampleInterface
,而我不能使用解决方法。(如果您想知道原因,请参考 此链接 )。码:
public void implementInterface(Clazz c) {
if (!(c instanceof ExampleInterface)) {
c.extendInterface(ExampleInterface {
@Override
public void run() {
//code
}
});
}
}
为了澄清,我遇到的问题是我需要 始终 知道何时run()
调用in
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
}
提出建议的唯一方法是使用字节码Instrumentation。您可以添加一个代理,该代理在加载之前更改要修改的clazz的字节码。
在加载时需要执行此操作的原因是,许多JVM不允许您更改字段,而某些JVM不允许您在类加载后添加方法。
一个更简单的解决方案是反编译该类,对其进行修改然后再次对其进行编译。假设可以反编译该类,这将节省大量时间和精力。
我正在使用的库中有一个安全管理器,它阻止所有反射的使用
这是一个奇怪的选择,因为您可以在调用库之前放置自己的SecurityManager,并且它不能阻止您执行任何操作。
问题内容: 例如,假设我想“提取” 为三个单独的变量,例如: 我该怎么做,而忽略了 “为什么要这么做呢?” 您可能会被问到这个问题。 之前已经多次问过类似的问题,但是从未给出真正的答案,因为OP真正需要的是使用不同的方法。很好,但这有可能吗? 我看过反射,似乎没有任何方法可以使我甚至向实例添加额外的字段,更不用说动态创建本地了。 问题答案: 是否可以在Java运行时创建变量? 简单回答是不。 Ja
问题内容: 现在我以下: 1)一个Java接口。 2),它的具体的java类 不 执行上述接口,但 不 包含的方法签名的接口中定义的方法中的每一个匹配。 由于我无法更改第2项的实现,因此我想知道是否可以使接受第1项实例作为参数的方法接受没有类强制转换的第2项。 感觉像Spring中的各种编织/强制/ AOP机制应该可以实现这一点,但是我不知道该怎么做。 有没有办法做到这一点? 问题答案: 您可以强
问题内容: 假设我在使用Java 8类型注释的类中具有以下成员: 是否可以在运行时使用反射读取在String类型上使用的给定注释?如果是这样,将如何进行? 更新:这是注释类型的定义: 问题答案: 是的,有可能。表示这种结构的反射类型称为。这是如何获取注释的示例:
问题内容: 我在运行时加载JSON配置文件,并使用接口定义其预期结构: 由于可以使用自动填充等功能,因此可以方便地访问各种属性。 问题: 有没有一种方法可以使用此声明来检查我加载的文件的正确性? 即我没有意外的属性? 问题答案: 没有。 当前,类型仅在开发和编译期间使用。类型信息不会以任何方式转换为已编译的JavaScript代码。
问题:有没有一种方法可以使用这个声明来检查我加载的文件的正确性?我没有意外的财产?
问题内容: 昨晚我在玩Java8 Lambda,我想知道是否有可能在运行时检索Lambda表达式。简而言之,据我所知,Lambda表达式在运行时被转换为(静态)方法,然后使用InvokeDynamics进行调用。 让我们举一个这样的例子: 其中将是以a 作为参数的自定义方法。在此方法内部,在这种情况下,如何以类似于Lambda表达式()的形式检索参数? 我尝试使用ASM5_BETA读取参数类的生成