我一直在玩注释,我想知道如何去做这件事。我想做的是能够在类中声明一个字段并注释,以便使用该类的静态实例初始化该字段。
给出这样的注释:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //or would this be RetentionPolicy.CLASS?
public @interface SetThisField {
}
这样的事情:
public class Foo {
@SetThisField
private Bar bar;
}
我已经玩过使用解析器并在运行时设置它,这可行,但不如我想的那么优雅。
我找不到RetentionPolicy.CLASS的任何真正好的例子,但是文档似乎表明我可以以某种方式将“bar”的声明编译成这个:
private Bar bar = Bar.getInstance();
当然,它在源代码中看起来不会这样,但它会在字节代码中运行,并且在运行时会表现得像那样。
我在这里离开吗?这可能吗?或者解析器是否可以使用它?
更新:这是我正在使用的解析器的内容
public static void parse(Object instance) throws Exception {
Field[] fields = instance.getClass().getDeclaredFields();
for (Field field : fields) {
//"Property" annotated fields get set to an application.properties value
//using the value of the annotation as the key into the properties
if (field.isAnnotationPresent(Property.class)) {
Property property = field.getAnnotation(Property.class);
String value = property.value();
if (!"".equals(value)) {
setFieldValue(instance, field, properties.getProperty(value));
}
}
//"Resource" annotated fields get static instances of the class allocated
//based upon the type of the field.
if (field.isAnnotationPresent(Resource.class)) {
String name = field.getType().getName();
setFieldValue(instance, field, MyApplication.getResources().get(name));
}
}
}
private static void setFieldValue(Object instance, Field field, Object value) throws IllegalAccessException {
boolean accessibleState = field.isAccessible();
field.setAccessible(true);
field.set(instance, value);
field.setAccessible(accessibleState);
}
答案 0 :(得分:2)
我建议在运行时进行替换。这更容易实现和测试。在构建时更改字节代码相对容易出错并且难以实现。例如,您需要了解字节代码的结构,在这种情况下,如何将代码添加到代码中正确位置的所有构造函数中。
如果你保留RUNTIME,你可以有一个库来检查注释并在创建对象后设置值。