java自定义注解属性类型受限:合法类型包括基本类型、string、class(需泛型约束如class

Java 自定义注解的属性类型不能随意指定,必须严格遵循语言规范。枚举数组和 Class 类型是两种常用且合法的选择,但用法有明确边界——错用会导致编译失败。
枚举类型及其数组完全支持
自定义枚举可直接作为注解成员类型,无需包装;其一维数组形式(MyEnum[])也完全合法。
- 定义枚举:确保使用
enum关键字,例如public enum ValidationLevel { LOW, MEDIUM, HIGH } - 在注解中声明:
ValidationLevel level() default ValidationLevel.MEDIUM;或ValidationLevel[] levels() default { ValidationLevel.LOW, ValidationLevel.HIGH }; - 使用时直接传入枚举常量或数组字面量,如
@Validate(level = ValidationLevel.HIGH)或@Validate(levels = {ValidationLevel.LOW, ValidationLevel.MEDIUM})
Class 类型必须用 Class> 或带泛型约束的形式
不能写 MyValidator check(),必须声明为 Class extends MyValidator> 或更宽松的 Class>。
- 推荐带泛型约束,体现类型安全:
Class extends Validator> validator() default DefaultValidator.class; - 默认值需为
.class字面量,如String.class、Object.class,不可为null或实例 - 运行时通过反射获取后,可用
clazz.getDeclaredConstructor().newInstance()实例化(需确保无参构造存在)
哪些类型绝对不允许出现在注解属性中
以下类型会触发编译错误 Invalid type,不可用于注解接口的方法返回值:
- 普通 Java 类(如
MyService、Config) - 接口类型(如
Runnable,即使它不是类) - 任意对象实例(包括
new ArrayList()或枚举实例本身) - 多维数组(如
String[][])、集合类(List<string></string>、Map<k></k>) -
void、Object、泛型未擦除的原始类型(如List.class是合法的,但List<string>.class</string>不合法)
组合使用枚举数组与 Class 的实用场景
常见于策略配置类注解,比如统一验证框架:
- 用枚举数组控制启用哪些校验阶段:
Phase[] phases() default { Phase.PRE_CHECK, Phase.POST_CHECK }; - 用
Class>[]指定多个处理器类:Class extends Handler>[] handlers() default {}; - 两者结合时,可在运行时按枚举顺序加载对应
Class实例,实现可插拔逻辑










