简体   繁体   English

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

[英]Java annotation to set field to a static instance?

I've been playing with annotations, and I'm wondering how to go about doing this. 我一直在使用批注,而我想知道如何去做。 What I'd like to do is to be able to have a field declared in a class and annotated such that the field will be initialized with a static instance of the class. 我想做的是能够在一个类中声明一个字段并对其进行注释,以便使用该类的静态实例来初始化该字段。

Given an annotation like this: 给定这样的注释:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //or would this be RetentionPolicy.CLASS?
public @interface SetThisField {
}

Something like this: 像这样:

public class Foo {

    @SetThisField
    private Bar bar;
}

I've played around with using a parser and setting this at runtime, which works but isn't as elegant as I'd like. 我一直在尝试使用解析器并在运行时进行设置,该方法可以运行,但并不如我所愿。

I can't find any really good examples of RetentionPolicy.CLASS but the documentation seems to indicate that I could somehow make the declaration of "bar" get compiled into this: 我找不到RetentionPolicy.CLASS的任何非常好的示例,但是文档似乎表明我可以通过某种方式使“ bar”的声明编译为以下内容:

private Bar bar = Bar.getInstance();

It wouldn't look that way in the source code of course, but it would in the byte code and it would behave like that at runtime. 当然,在源代码中看起来不会那样,但是在字节代码中看起来会那样,并且在运行时的行为也是如此。

So am I off base here? 那我在这里基地了吗? Is this possible? 这可能吗? Or is the parser the way to go with it? 还是解析器与之配套?

UPDATE: This is the guts of the parser I'm using 更新:这是我正在使用的解析器的胆量

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

I would suggest doing the replacement at run time. 我建议在运行时进行更换。 This is much simpler to implement and test. 这更容易实现和测试。 Changing the byte code at build time is relatively error prone and tricky to get right. 在构建时更改字节码相对容易出错,并且很难正确设置。 For example you would need to understand how byte code is structured and in this case how to add the code to all the constructors in the right place in the code. 例如,您需要了解字节代码的结构,在这种情况下,如何将代码添加到代码中正确位置的所有构造函数中。

If you make the retention RUNTIME, you can have a library which examines the annotation and sets the value after the object is created. 如果使保留时间为RUNTIME,则可以有一个库,该库检查注释并在创建对象后设置值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM