自定义注解成员类型仅限基本类型、string、class、枚举、其他注解及一维数组,default值须为编译期常量且数组需用{}显式声明,无default则使用时必须赋值。

自定义注解中,成员变量(即注解元素)的默认值和类型有明确限制,不能随意设定。
成员变量必须是编译期常量类型
注解成员只能使用以下类型之一:基本类型(int、boolean、char等)、String、Class、枚举类型、其他注解类型,以及上述类型的一维数组。不能使用集合(如 List、Map)、泛型类、自定义对象或任何运行时才能确定的值。
- ✅ 合法:String value() default "hello";
- ✅ 合法:int[] ids() default {1, 2, 3};
- ✅ 合法:MyEnum type() default MyEnum.NORMAL;
- ❌ 非法:List
names() default new ArrayList(); - ❌ 非法:Object data() default null;
default 值必须是编译时常量表达式
指定 default 时,其值必须在编译期就能完全确定,不能调用方法、访问变量或依赖运行时逻辑。
- ✅ 合法:String name() default "admin";
- ✅ 合法:int version() default 1 + 2 * 3;(算术常量表达式)
- ✅ 合法:Class> clazz() default Void.class;
- ❌ 非法:String now() default System.currentTimeMillis() + "";
- ❌ 非法:String path() default System.getProperty("user.home");
数组类型 default 必须显式写成大括号形式
即使只设一个元素,数组类型的默认值也必须用 {} 包裹,否则编译报错。
- ✅ 合法:String[] roles() default {"USER"};
- ✅ 合法:Class>[] excludes() default {};(空数组)
- ❌ 非法:String[] tags() default "tag1";
- ❌ 非法:int[] codes() default 404;
没有 default 时,使用注解必须显式赋值
若某个成员未声明 default,则所有使用该注解的地方都必须为它提供值,否则编译失败。可将最常用值设为 default 提升易用性。
- 定义:@interface Log { String value() default ""; int level() default 2; }
- 使用:@Log(level = 1) ✅(value 可省略)
- 使用:@Log ✅(两个都有 default)
- 若去掉 level() 的 default,则 @Log 会编译失败









