Get annotations for enum type variable

前端 未结 5 946
孤城傲影
孤城傲影 2020-12-29 02:34

I have some nonnull variable (e.g. en1) of Enum type. The question is: how to get annotations related to enumeration constant referenced by e

相关标签:
5条回答
  • 2020-12-29 02:46

    I just read from your comment that you already found the answer. I just wanted to remark for other people interested that, in order for that to work, those annotations must have been declared with the correct retention policy, like this:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Anno1 {
       // ...
    }
    

    Without this, they will not be accessible at runtime.

    Further reading:

    • JavaDoc: RetentionPolicy
    • Wikipedia: Java annotation
    0 讨论(0)
  • 2020-12-29 02:49

    Try this (java reflection):

    String field = En.AAA.name();
    En.class.getField(field).getAnnotations();
    

    It should get you the annotations from AAA.

    EDIT:

    As the author supposed:

    en1.getClass().getField(((Enum)en1).name()).getAnnotations(); 
    

    Works for him :)

    0 讨论(0)
  • 2020-12-29 02:51

    Further to the existing answers, if you are in control of the enum class (can edit it), you could simply add a method to the enum to fetch the required annotation i.e.

    AnnotationClass getAnnotation(){
       Field field = this.getClass().getField(this.name());
       return field.getAnnotation(AnnotationClass.class);       
    }
    

    or all it's annotations:

    Annotation[] getAnnotations(){
       Field field = this.getClass().getField(this.name());
       return field.getAnnotations();
    }
    

    Adjust the code above to handle exceptions (NoSuchFieldException and SecurityException).

    0 讨论(0)
  • 2020-12-29 02:54

    If you are using an obfuscator such as Proguard, you might find that the enum fields have been renamed, while .name() still returns the original name of the field. For example, this enum...

    enum En {
        FOO,
        BAR
    }
    

    ...would become this after ProGuarding...

    enum En {
        a,
        b
    }
    

    ...but En.FOO.name() will still return "FOO", causing getField(En.FOO.name()) to fail because it expects the field to be named "a".

    If you want to get the Field for a specific enum field from obfuscated code, you can do this:

    for (Field field : En.class.getDeclaredFields()) {
        if (field.isEnumConstant()) {
            try {
                if (en1 == field.get(null)) {
                    Annotation[] annotations = field.getAnnotations();
                }
            } catch (IllegalAccessException e) {
                // 
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-29 02:56

    As I've already offered:

    en1.getClass().getField(((Enum)en1).name()).getAnnotations();
    

    To be clearer:

    String name = e.name(); // Enum method to get name of presented enum constant
    Annotation[] annos = e.getClass().getField(name).getAnnotations(); // Classical reflection technique
    

    In this case we have no need to know real class of en1.

    See also: remark about obfuscated case.

    0 讨论(0)
提交回复
热议问题