Java注释将字段设置为静态实例?

时间:2013-05-31 21:10:29

标签: java annotations bytecode

我一直在玩注释,我想知道如何去做这件事。我想做的是能够在类中声明一个字段并注释,以便使用该类的静态实例初始化该字段。

给出这样的注释:

@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);
}

1 个答案:

答案 0 :(得分:2)

我建议在运行时进行替换。这更容易实现和测试。在构建时更改字节代码相对容易出错并且难以实现。例如,您需要了解字节代码的结构,在这种情况下,如何将代码添加到代码中正确位置的所有构造函数中。

如果你保留RUNTIME,你可以有一个库来检查注释并在创建对象后设置值。