我正在使用java 6注释处理api。我已经按照以下优秀教程创建了一个在构建时显示消息的注释处理器:
http://kerebus.com/2011/02/using-java-6-processors-in-eclipse/
但是,在我的情况下,我有一个简单的类:
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface Criteria {
String id();
double width();
double height();
}
如您所见,上述注释在运行时使用元注释“Retention”提供给JVM。我在另一个类的源代码中使用这个“Criteria”注释来注释一个方法,如下所示:
@Criteria(id = "fooBar",
width = 22,
height = 10
)
public void fooStream() {
System.out.println("foo stream method");
}
在运行时,我想在另一个类中包含'fooStream'方法,仅当传入的变量与@Criteria注释中的元素值匹配时,即'width'和'height'。我的问题是,如何在运行时将方法'fooStream'并将其注入另一个类?这甚至可能吗?我不是在寻找任何代码示例,只是回答上述两个问题。此外,在顶部的链接中,有一个使用'JavaFileObject'和'Writer'实例生成代码的示例,其中生成的代码作为字符串传递。
答案 0 :(得分:4)
我不相信Java支持运行时类型变异,这意味着修改给定类上的成员,你必须回退到编译时预处理器或字节码修改方案。
如果我理解这个问题背后的“为什么”,我能指出你更好的方向,但同时,dynamic proxy classes可能会让你到达你想要的地方({{3 }})。
来自文档:
动态代理类是一个类 实现接口列表 在运行时指定,以便a 通过其中一个方法调用 类的实例上的接口 将被编码并发送给 通过制服的另一个对象 接口。因此,一个动态代理类 可用于创建类型安全 接口列表的代理对象 无需预先生成 代理类,例如with 编译时工具。 方法调用 在动态代理的实例上 class被派遣到一个单独的 实例调用中的方法 处理程序,它们用a编码 java.lang.reflect.Method对象 确定方法 调用和Object类型的数组 包含参数。
使用Spring根据自定义注释注入动态代理是一个不错的JavaWorld article。我认为这可能与你所追求的行为最为接近。
答案 1 :(得分:0)
如果您想要对类进行运行时修改,您可以使用自己的类加载器并拦截类的加载,内省您想要的内容并使用asm库而不是原始类生成新的字节码。这不是很棘手,但你必须确定你需要的确如此。