【发布时间】:2011-10-27 15:07:23
【问题描述】:
Java 允许 enum 作为注释值的值。如何为enum 注释值定义一种通用的默认enum 值?
我已经考虑了以下,但它不会编译:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public <T extends Enum<T>> @interface MyAnnotation<T> {
T defaultValue();
}
这个问题有没有解决办法?
赏金
似乎没有针对这种 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 提供了一个优雅的解决方案来摆脱带注释字段中的clazz:
@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 以获取提供的默认值。
这需要为每个枚举类型创建一个注解类型,但保证编译时检查类型的安全性。
【问题讨论】:
-
那不是没有意义吗?每当您在运行时处理注释时,通用信息就会丢失。
-
这样可以避免我必须为每个枚举类型定义一个注释以便在我的代码中使用(这是一个编译时问题)。
-
我并不是说这个想法没有用。但是泛型仅在编译时才知道。您已将注释标记为在运行时中保留。但是要访问注释,你必须通过反射——你不会知道泛型最初是什么。
-
好的,但我对在运行时了解泛型类型不感兴趣。如果构造函数中没有提供对象的枚举字段值(例如),我只想确保在我启动对象的枚举字段值时手头有一个默认值。
-
您使用注释声明默认值的用例是什么,而您无法使用简单的
private MyEnum field = MyEnum.DEFAULT;?
标签: java enums annotations default-value