枚举枚举枚举枚举值枚举值

Java允许枚举作为注释值的值。如何为枚举注释值定义一种通用的默认枚举值?

我考虑过以下,但不会编译:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public <T extends Enum<T>> @interface MyAnnotation<T> {

    T defaultValue();

}

有没有解决这个问题?

BOUNTY

似乎没有直接解决这个Java角色的情况。所以,我开始一个赏金找到这个问题的最优雅的解决方案。

理想的解决方案应该满足以下标准:

>所有枚举之间的一个注释可重用
>从注释实例中检索默认枚举值作为枚举的最小工作量/复杂度

最佳解决方案

沙丘:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {

    // By not specifying default,
    // we force the user to specify values
    Class<? extends Enum<?>> enumClazz();
    String defaultValue();

}

...

public enum MyEnumType {
    A, B, D, Q;
}

...

// Usage
@MyAnnotation(enumClazz=MyEnumType.class, defaultValue="A"); 
private MyEnumType myEnumField;

当然,我们无法强制用户在编译时指定有效的默认值。但是,任何注释预处理都可以使用valueOf()来验证。

改进

Arian提供了一个优雅的解决方案来摆脱注释领域中的残酷:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {

}

...

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@MyAnnotation()
public @interface MyEnumAnnotation {

    MyEnumType value(); // no default has user define default value

}

...

@MyEnumAnnotation(MyEnum.FOO)
private MyEnumType myValue;

注释处理器应在所提供的默认值的字段上搜索MyEnumAnnotation。

这需要每个枚举类型创建一个注释类型,但保证编译时检查类型的安全性。

我不知道你的用例是什么,所以我有两个答案:

答案1:

如果你只是想尽可能少的代码,这里是我的建议延伸Dunes的答案:

public enum ImplicitType {
    DO_NOT_USE;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {

    Class<? extends Enum<?>> clazz() default ImplicitType.class;

    String value();
}

@MyAnnotation("A"); 
private MyEnumType myEnumField;

当clazz是ImplicitType.class时,请使用类型为enum类的字段。

答案2:

如果你想做一些框架魔术,并希望保持编译器检查类型的安全性,你可以这样做:

/** Marks annotation types that provide MyRelevantData */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface MyAnnotation {
}

在客户端代码中,你会有

/** Provides MyRelevantData for TheFramework */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@MyAnnotation
public @interface MyEnumAnnotation {

    MyEnumType value(); // default MyEnumType.FOO;

}

@MyEnumAnnotation(MyEnum.FOO)
private MyEnumType myValue;

在这种情况下,您将扫描字段以注释,再次使用MyAnnotation进行注释。但是,您必须通过反射对注释对象来访问该值。像这样的方法似乎在框架方面更为复杂。

翻译自:https://stackoverflow.com/questions/7071301/enum-default-value-for-java-enum-annotation-value

转载注明原文:枚举枚举枚举枚举值枚举值