Annotations arrived with version 49.0 (J2SE 5.0) and type annotations with 52.0
(Java SE 8). An annotation whose retention is RUNTIME goes in a
RuntimeVisible attribute, which reflection reads; one whose retention is
CLASS, the default, goes in a RuntimeInvisible attribute, kept for
tools but not loaded. SOURCE annotations are not written at all. The
seven attributes share two structures, annotation and
element_value. How annotations are declared and used in the source is on
the Java annotations page.
RuntimeVisibleAnnotations
On a class, field, method or record component: its annotations with run-time retention, at most one such attribute per structure.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | num_annotations | The number of annotations |
| 8 | varies | annotation[] | annotations | Each an annotation |
RuntimeInvisibleAnnotations
The same layout, for annotations with class retention. The JVM does not load them unless told to; compilers, bytecode tools and static analysers read them.
annotation
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | u2 | type_index | A Utf8 entry: the annotation interface as a field descriptor, such as Ljava/lang/Deprecated; |
| 2 | 2 | u2 | num_element_value_pairs | The number of elements given values |
| 4 | 2 | u2 | element_name_index | A Utf8 entry: the element’s name, such as value |
| 6 | varies | element_value | value | Its value |
The last two fields repeat for each pair. Elements left at their defaults are not written; their defaults are in the annotation interface’s AnnotationDefault attributes.
element_value
A one-byte tag, an ASCII character, then the value in a form the tag decides:
| Tag | Type | Then |
|---|---|---|
B | byte | u2 const_value_index: an Integer entry |
C | char | u2 const_value_index: an Integer entry |
D | double | u2 const_value_index: a Double entry |
F | float | u2 const_value_index: a Float entry |
I | int | u2 const_value_index: an Integer entry |
J | long | u2 const_value_index: a Long entry |
S | short | u2 const_value_index: an Integer entry |
Z | boolean | u2 const_value_index: an Integer entry, 0 or 1 |
s | String | u2 const_value_index: a Utf8 entry (not a String entry) |
e | enum constant | u2 type_name_index: a Utf8 entry with the enum class’s descriptor; u2 const_name_index: a Utf8 entry with the constant’s name |
c | Class | u2 class_info_index: a Utf8 entry with a return descriptor, such as Ljava/lang/String;, or V for void.class |
@ | annotation | a nested annotation |
[ | array | u2 num_values, then that many element_values (an array of arrays is not allowed in the language) |
For example @Retention(RetentionPolicy.RUNTIME) is
type_index → Ljava/lang/annotation/Retention;, one pair, name
value, then tag e (65) with
Ljava/lang/annotation/RetentionPolicy; and RUNTIME.
RuntimeVisibleParameterAnnotations
On a method: run-time annotations on its parameters.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 1 | u1 | num_parameters | The number of parameters covered (one byte) |
| 7 | 2 | u2 | num_annotations | For the first parameter: the number of annotations |
| 9 | varies | annotation[] | annotations | Its annotations |
The count and the annotations repeat for each parameter, in order.
num_parameters may be smaller than the number of parameters in the
descriptor: compilers may leave out parameters that are not in the source, such as the
outer object passed to an inner class’s constructor.
RuntimeInvisibleParameterAnnotations
The same layout, for parameter annotations with class retention.
AnnotationDefault
On a method of an annotation interface: the element’s default value, from the
default clause.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | varies | element_value | default_value | The value |
RuntimeVisibleTypeAnnotations
From 52.0: annotations on uses of types, such as List<@NonNull String>
or (@Nullable Object) x. Allowed on a class, field, method, record
component and Code attribute.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | num_annotations | The number of type annotations |
| 8 | varies | type_annotation[] | annotations | Each as below |
Each type_annotation says which type it annotates, then holds an
ordinary annotation:
| Size | Type | Name | Meaning |
|---|---|---|---|
| 1 | u1 | target_type | The kind of type use, which decides the target_info (see target types) |
| varies | target_info | Which one of that kind | |
| varies | target_path | Where inside the type (see type path) | |
| 2 | u2 | type_index | As in an annotation |
| 2 | u2 | num_element_value_pairs | As in an annotation |
| varies | pairs | As in an annotation |
RuntimeInvisibleTypeAnnotations
The same layout, for type annotations with class retention.
Target types
Types 0x00 to 0x17 may appear in the attributes of a class, field, method or record component; 0x40 to 0x4B only in those of a Code attribute, where they refer to the bytecode.
| target_type | Annotates | target_info |
|---|---|---|
| 0x00 | a type parameter of a generic class or interface | u1 type_parameter_index |
| 0x01 | a type parameter of a generic method or constructor | u1 type_parameter_index |
| 0x10 | a type in an extends or implements clause | u2 supertype_index: 65535 for the superclass, otherwise an index into interfaces |
| 0x11 | a bound of a class’s type parameter | u1 type_parameter_index, u1 bound_index |
| 0x12 | a bound of a method’s type parameter | u1 type_parameter_index, u1 bound_index |
| 0x13 | the type of a field or record component | empty |
| 0x14 | a method’s return type, or the type of a newly made object | empty |
| 0x15 | the receiver type of a method or constructor | empty |
| 0x16 | the type of a formal parameter | u1 formal_parameter_index |
| 0x17 | a type in a throws clause | u2 throws_type_index: an index into the Exceptions attribute |
| 0x40 | the type of a local variable | u2 table_length, then for each: u2 start_pc, u2 length, u2 index |
| 0x41 | the type of a resource variable in try | as 0x40 |
| 0x42 | the type of an exception parameter in catch | u2 exception_table_index |
| 0x43 | the type in an instanceof | u2 offset of the instruction |
| 0x44 | the type in a new | u2 offset |
| 0x45 | the type in a method reference ::new | u2 offset |
| 0x46 | the type in a method reference ::name | u2 offset |
| 0x47 | the type in a cast | u2 offset, u1 type_argument_index |
| 0x48 | a type argument of a generic constructor in new or an explicit constructor call | u2 offset, u1 type_argument_index |
| 0x49 | a type argument of a generic method call | u2 offset, u1 type_argument_index |
| 0x4A | a type argument of a generic constructor in ::new | u2 offset, u1 type_argument_index |
| 0x4B | a type argument of a generic method in ::name | u2 offset, u1 type_argument_index |
The explorer turns down a type annotation with any other target type.
Type path
The target says which type is annotated; the path says which part of it. For
@A Map<@B String, @C List<@D Object>>, @A has an empty path,
@B the path “type argument 0”, @C “type argument 1” and @D “type argument 1, then
type argument 0”.
| Size | Type | Name | Meaning |
|---|---|---|---|
| 1 | u1 | path_length | The number of steps; 0 for the type itself |
| 1 | u1 | type_path_kind | Which way to step (below) |
| 1 | u1 | type_argument_index | For kind 3, which type argument, from 0; otherwise 0 |
The last two fields repeat for each step.
| type_path_kind | Step |
|---|---|
| 0 | deeper into an array type: to its element type |
| 1 | deeper into a nested type: to the inner class of an outer type |
| 2 | to the bound of a wildcard type argument |
| 3 | to one of the type arguments of a parameterised type |