What is special about an annotation element named 'value', and how does it enable the @Anno("x") shorthand?
answer
- element named exactly value
- @Anno("x") == @Anno(value = "x")
- only when value is the lone required element
- can't mix bare value with a named element
- works with array shorthand too
basics
~10 sIf an element is named exactly 'value', you can set it without naming it: @Anno("x") means @Anno(value = "x"). It works only when value is the only element you need to supply.
solid answer
~40 sAn element literally named value gets special treatment: when you apply the annotation you may give just the bare value and skip value =. So @SuppressWarnings("unchecked") is shorthand for @SuppressWarnings(value = "unchecked"). The shorthand is allowed only when value is the sole element you must specify, every other element must either have a default or also be omittable, otherwise you have to switch back to the named form @Anno(value = ..., other = ...). It also works for arrays: if value is String[], then @Anno("x") expands to @Anno(value = {"x"}). This is purely a syntactic convenience the compiler recognizes by the name value; there's nothing else magic about it. It's why so many common annotations expose a single value element, it reads cleanly at the call site.
go deeper
Recognizes that @Anno("x") is shorthand for setting an element named value.
States the precise condition (value is the only element needing a value; others must default) and that you can't mix bare value with a named element.
Combines the value shorthand with single-element-array shorthand and gives design guidance: name the primary attribute value and default the rest.
Treats the value convention as an API-design tool for call-site ergonomics and considers how it interacts with annotation evolution and repeatable/container annotations.
## The convention Java singles out one element name: **`value`**. If your annotation has an element named exactly `value`, callers can omit the `value =` prefix and just write the value directly: ```java public @interface Role { String value(); } @Role("ADMIN") // shorthand @Role(value = "ADMIN") // equivalent, explicit form class AdminController {} ``` Both lines mean the same thing. You've seen this everywhere: `@SuppressWarnings("unchecked")`, `@RequestMapping("/users")`, `@Qualifier("primary")`. ## The exact rule for when shorthand is legal The bare-value form is permitted **only if `value` is the only element that needs an explicit value**. Concretely: - The annotation has an element named `value`, **and** - every *other* element either has a `default` (so it can be omitted) or you don't intend to set it. If you also want to set another element, you must use the fully named form for *all* of them: ```java public @interface Cache { String value(); // the key int ttl() default 60; } @Cache("users") // ok: ttl defaults @Cache(value = "users", ttl = 30) // must name value once you add ttl @Cache("users", ttl = 30) // COMPILE ERROR: can't mix bare value with a named element ``` ## Arrays and `value` If `value` is an array element, the single-element-array shorthand combines with the `value` shorthand: ```java public @interface Tags { String[] value(); } @Tags("a") // == @Tags(value = {"a"}) @Tags({"a", "b"}) // == @Tags(value = {"a", "b"}) ``` ## Why it exists / design guidance It's pure ergonomics: many annotations have one obviously-primary attribute, and forcing `value =` everywhere would be noisy. When **designing** an annotation, name its primary attribute `value` and give every other element a default so the common usage is the clean `@Anno("x")`. ## Pitfalls - The element must be named **exactly** `value`, not `values`, not `name`. Any other name forfeits the shorthand. - You **cannot** mix bare value with a named element (`@Cache("users", ttl = 30)` is illegal); once a second element appears you must name `value` too. - A *marker* annotation has no `value` element and takes no shorthand, it's just `@Anno`.
- Can you write @Cache("users", ttl = 30) when value is the key element?No. Once you set a second element you must name value too: @Cache(value = "users", ttl = 30). Mixing bare value with a named element doesn't compile.
- Does the shorthand work if the element is named valueText?No. The element must be named exactly value; any other name forfeits the bare-value shorthand.
saying these in an interview costs you the question
- Thinking the shorthand works for any element name
- Mixing bare value with another named element
- Believing it's special compiler magic beyond the name match
- Assuming @Anno("x") works when other elements lack defaults