【问题标题】:Using Java Annotations - Generating Code使用 Java 注释 - 生成代码
【发布时间】:2011-06-03 15:47:07
【问题描述】:

我正在使用 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();
}

如您所见,上述注解可在运行时使用元注解“保留”提供给 JVM。我在另一个类的源代码中使用这个'Criteria'注释来注释一个方法,如下所示:

@Criteria(id = "fooBar", 
    width = 22, 
    height = 10
)
public void fooStream() {       
    System.out.println("foo stream method");
} 

在运行时,我想在另一个类中包含“fooStream”方法,前提是传入的变量与@Criteria 注释中元素的值匹配,即“宽度”和“高度”。我的问题是,我怎样才能在运行时采用方法 'fooStream' 并将其注入另一个类?这甚至可能吗?我不是在寻找任何代码示例,只是对上述两个问题的回答。此外,在顶部的链接中,有一个使用“JavaFileObject”和“Writer”实例生成代码的示例,其中生成的代码作为字符串传递。

【问题讨论】:

  • 您要问的是,在运行时将方法注入另一个类,不会用 java 编程语言计算。 Java中没有函数。您更多的是尝试在 JVM 上创建自己的新编程语言。
  • 您能解释一下您要解决什么问题吗?你将如何在一个不知道它的类中使用外星方法?

标签: java annotations


【解决方案1】:

我不相信 Java 支持运行时类型突变,这意味着要修改给定类的成员,您必须退回到编译时预处理器或字节码修改方案。

如果我理解这个问题背后的“为什么”,我可以为您指明一个更好的方向,但与此同时,dynamic proxy classes 可能会让您到达您想去的地方 (JavaWorld article)。

来自文档:

动态代理类是一个类 实现接口列表 在运行时指定,使得 通过其中一种方法调用 类实例上的接口 将被编码并发送到 穿过制服的另一个物体 界面。因此,动态代理类 可用于创建类型安全的 接口列表的代理对象 无需预生成 代理类,例如 with 编译时工具。 方法调用 在动态代理的实例上 类被分派到单个 实例调用中的方法 处理程序,它们被编码为 java.lang.reflect.Method 对象 识别方法 调用和一个对象类型的数组 包含参数。

这里有一个不错的tutorial,关于使用 Spring 基于自定义注释注入动态代理。我认为这可能最接近您所追求的行为。

【讨论】:

  • 问题背后的“为什么”是我将在 jax-ws Web 服务中包含上述代码。但是,如果满足注释中定义的条件,我只想触发该方法。我不想使用大量的“if/else”语句,因此注释是我指定何时应在运行时将方法包含在 Web 服务中的一种方式。这有意义吗?
  • 是的。动态代理仍然是要走的路。编写字节码修改方案并不简单,如果你只是想避免一些复杂的条件,那就太矫枉过正了。
【解决方案2】:

如果您想在运行时修改您的,您可以使用自己的类加载器并拦截类的加载,内省您想要的内容并使用 asm 库而不是原始类生成新的字节码。这不是很棘手,但您必须确定您确实需要它。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 2011-01-03
相关资源
最近更新 更多