java自定义注解中,若唯一非默认属性名为value,可省略“value =”直接传值;若存在其他无默认值属性则不可简写;value名不可更改,数组类型简写需按单/多元素规范加括号;运行时读取需@retention(runtime)。

当自定义注解只有一个属性,且该属性名为 value 时,Java 允许省略 value = 这部分写法,直接写值——这就是所谓的“单值传递简写糖语法”。它不是语法糖的炫技,而是为提升可读性和减少冗余设计的实用约定。
value 属性必须是唯一非默认属性
要启用简写,注解中 不能有其他未设默认值的属性。只要存在另一个无默认值的成员(比如 level() 或 message()),即使你只传了 value,编译器也会报错,强制你显式写出所有必填项。
- ✅ 正确:仅含
String value() default "ok";或String value();(此时使用时必须赋值) - ❌ 错误:同时定义
String value();和int code();→ 使用时必须写成@MyAnno(value="x", code=200),无法简写
声明方式:用 default 赋默认值可选,但 value 名字不能变
value 是关键字角色,不是固定保留字,但它在注解里被 JVM 特殊识别——只有方法名恰好叫 value,且是唯一需显式赋值的属性时,才能触发简写机制。
- 定义示例:
public @interface Log { String value() default "INFO"; } - 使用简写:
@Log("DEBUG")→ 等价于@Log(value = "DEBUG") - 若改名成
level(),哪怕它是唯一属性,也必须写成@Log(level = "DEBUG")
数组类型 value 的简写规则
如果 value 是数组类型(如 String[] value()),简写依然有效,但赋值格式需注意:
- 单个元素:直接写值,不加花括号 ——
@Roles("admin") - 多个元素:必须用大括号包裹 ——
@Roles({"admin", "user"}) - 空数组:写成
@Roles({}),不能省略{}
运行时能读到吗?得看 @Retention
简写只是编译期语法优化,和运行时无关。若想在代码中通过反射获取这个 value 值,注解定义上必须加上:
@Retention(RetentionPolicy.RUNTIME)否则反射调用 getAnnotation(MyAnno.class).value() 会返回 null 或抛异常。










