Attributes carry everything a class file holds beyond its bare outline: a method’s bytecode, a field’s constant value, generic signatures, annotations, debugging information. The class, each field, each method, each Code attribute and each record component end with a list of them. Every attribute names itself and gives its length, so a reader can skip any it does not know. That is how the format has grown since 1996 without breaking old readers.
attribute_info
Each list is a u2 attributes_count followed by that many attributes,
each of this shape:
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | u2 | attribute_name_index | A Utf8 entry: the attribute’s name, such as Code |
| 2 | 4 | u4 | attribute_length | The number of bytes that follow, not counting these six |
| 6 | attribute_length | u1[] | info | The body, whose layout the name decides |
The order of attributes in a list does not matter. Names are matched exactly and are
case-sensitive. The explorer reads each attribute the specification defines field by
field, inside a window of exactly attribute_length bytes, so a body
longer or shorter than its fields is found at once and the file is turned down.
Unknown and misplaced attributes
A JVM must ignore attributes it does not recognise, and compilers and tools may define their own, as long as the names do not clash with the specification’s. An attribute the specification defines but in the wrong place, such as a ConstantValue on a method, is ignored too. The explorer shows both as plain bytes: an unknown attribute as “not a standard attribute”, a misplaced one as “misplaced”.
Attributes from other tools seen in old class files examined for this site:
StackMap: written by the CLDC preverifier for Java ME phones; the explorer reads it, see StackMap;SGILineNumberandSGIDeclDefnExtents: apparently from SGI’s Java compiler, in 1990s applets;AbsoluteSourcePathandFastJavac3.0: from other compilers and tools of the 1990s;(C) saviour ::: komplex: an attribute whose name is a signature, in some applet demos.
The predefined attributes
The JVM Specification (Java SE 25, table 4.7-A) defines thirty attributes. Each may appear only in the places listed and only in files of its version or later.
| Attribute | From | Where | Purpose |
|---|---|---|---|
| ConstantValue | 45.3 | field | A constant field’s value |
| Code | 45.3 | method | The bytecode |
| Exceptions | 45.3 | method | The throws clause |
| SourceFile | 45.3 | class | The source file’s name |
| LineNumberTable | 45.3 | Code | Source line numbers |
| LocalVariableTable | 45.3 | Code | Local variable names and types |
| InnerClasses | 45.3 (JDK 1.1) | class | Nested classes and their source modifiers |
| Synthetic | 45.3 (JDK 1.1) | class, field, method | Not in the source |
| Deprecated | 45.3 (JDK 1.1) | class, field, method | Marked deprecated |
| EnclosingMethod | 49.0 | class | Where a local or anonymous class is declared |
| Signature | 49.0 | class, field, method, record component | The generic type |
| SourceDebugExtension | 49.0 | class | Debugging data for other languages |
| LocalVariableTypeTable | 49.0 | Code | Generic types of local variables |
| RuntimeVisibleAnnotations | 49.0 | class, field, method, record component | Annotations reflection can see |
| RuntimeInvisibleAnnotations | 49.0 | class, field, method, record component | Annotations kept for tools only |
| RuntimeVisibleParameterAnnotations | 49.0 | method | Parameter annotations reflection can see |
| RuntimeInvisibleParameterAnnotations | 49.0 | method | Parameter annotations for tools only |
| AnnotationDefault | 49.0 | method | An annotation element’s default |
| StackMapTable | 50.0 | Code | Type frames for the verifier |
| BootstrapMethods | 51.0 | class | Bootstrap methods for invokedynamic and dynamic constants |
| RuntimeVisibleTypeAnnotations | 52.0 | class, field, method, Code, record component | Type annotations reflection can see |
| RuntimeInvisibleTypeAnnotations | 52.0 | class, field, method, Code, record component | Type annotations for tools only |
| MethodParameters | 52.0 | method | Parameter names and flags |
| Module | 53.0 | class (module-info) | The module declaration |
| ModulePackages | 53.0 | class (module-info) | Every package in the module |
| ModuleMainClass | 53.0 | class (module-info) | The module’s main class |
| NestHost | 55.0 | class | The top-level class of this class’s nest |
| NestMembers | 55.0 | class | The other classes of the nest |
| Record | 60.0 | class | A record class’s components |
| PermittedSubclasses | 61.0 | class | The subclasses a sealed class allows |
Seven of these are needed for the JVM to run the class correctly: ConstantValue,
Code, StackMapTable, BootstrapMethods, NestHost, NestMembers and PermittedSubclasses.
The rest serve the class libraries, compilers, debuggers and reflection. The
sections below give the bodies of the class, field and method attributes; Code and
its attributes, StackMapTable, annotations and modules have pages of their own.
Offsets count from the start of the attribute, so 6 is the first byte after
attribute_length.
ConstantValue
On a field: the constant value a static field starts with. The length is always 2.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | constantvalue_index | An Integer entry for int, short, char, byte and boolean fields; Float, Long or Double for those types; String for a String field |
The JVM sets the field from it when the class is initialised, before
<clinit> runs. On a field that is not static it is ignored.
Exceptions
On a method: the checked exceptions in its throws clause. The JVM does not
enforce it; the compiler and reflection use it.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | number_of_exceptions | The number of entries |
| 8 | 2 × n | u2[] | exception_index_table | Class entries, one per exception class |
InnerClasses
On a class: every nested class it declares, every class it is nested in, and every nested class it refers to. Each entry is 8 bytes.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | number_of_classes | The number of entries |
| 8 + 8i | 2 | u2 | inner_class_info_index | A Class entry: the nested class |
| 10 + 8i | 2 | u2 | outer_class_info_index | A Class entry: the class it is a member of; 0 for a local or anonymous class |
| 12 + 8i | 2 | u2 | inner_name_index | A Utf8 entry: its simple name as in the source; 0 for an anonymous class |
| 14 + 8i | 2 | u2 | inner_class_access_flags | The flags it was declared with |
A nested class is compiled to a class file of its own, named with $:
Map$Entry.class, or Outer$1.class for the first anonymous
class. This attribute is how the two files know about each other.
EnclosingMethod
On a local or anonymous class: where it was declared. The length is always 4.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | class_index | A Class entry: the innermost class that encloses it |
| 8 | 2 | u2 | method_index | A NameAndType entry: the enclosing method or constructor; 0 when it is not inside one, such as in a field initialiser |
Synthetic
On a class, field or method: the member does not appear in the source. It has no body; the length is 0. From 49.0 the ACC_SYNTHETIC flag says the same, and compilers use the flag instead.
Deprecated
On a class, field or method: it is deprecated, by the @deprecated
Javadoc tag or the @Deprecated annotation. It has no body; the length is
0. The JVM ignores it; the compiler warns when deprecated code is used.
Signature
On a class, field, method or record component whose type uses generics. The length is always 2.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | signature_index | A Utf8 entry: a class, method or field signature |
SourceFile
On a class: the name of the file it was compiled from, without any folder, such as
EmptyStackException.java. Stack traces show it. The length is always
2.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | sourcefile_index | A Utf8 entry: the file name |
00 0C 00 00 00 02 00 09: name #12 (SourceFile), length 2,
file name #9.
SourceDebugExtension
On a class: extra debugging information, at most one. It is used for classes compiled from languages other than Java, such as JSP pages, to map the bytecode back to their source (JSR 45’s SMAP format).
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | attribute_length | u1[] | debug_extension | A string in modified UTF-8, with no length field and no terminator |
BootstrapMethods
On a class: the bootstrap methods that link its invokedynamic call sites
and compute its Dynamic constants. InvokeDynamic and Dynamic entries refer to this
table by position, from 0.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | num_bootstrap_methods | The number of entries |
| … | 2 | u2 | bootstrap_method_ref | A MethodHandle entry: the bootstrap method |
| … | 2 | u2 | num_bootstrap_arguments | The number of static arguments |
| … | 2 × n | u2[] | bootstrap_arguments | Loadable constants passed to the bootstrap method |
The last three fields repeat for each entry. A lambda is linked by
LambdaMetafactory.metafactory with three arguments: the erased method
type, a handle to the lambda’s body and the specialised method type.
MethodParameters
On a method: its parameters’ names and flags, for reflection. javac writes it when
given the -parameters option.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 1 | u1 | parameters_count | The number of parameters (one byte) |
| 7 + 4i | 2 | u2 | name_index | A Utf8 entry: the name; 0 for a parameter with no name |
| 9 + 4i | 2 | u2 | access_flags | final, synthetic, mandated |
NestHost
On a nested class: the top-level class of its nest. Classes of one nest may use each other’s private members directly (Java 11 and later). The length is always 2.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | host_class_index | A Class entry: the nest host |
NestMembers
On a top-level class: the other members of its nest, which each name it in their NestHost. A class has NestHost or NestMembers, never both.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | number_of_classes | The number of entries |
| 8 | 2 × n | u2[] | classes | Class entries, one per nest member |
Record
On a record class: its components, in order. The class still has its private final fields and accessor methods; this attribute records which they are.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | components_count | The number of components |
| … | 2 | u2 | name_index | A Utf8 entry: the component’s name |
| … | 2 | u2 | descriptor_index | A Utf8 entry: its field descriptor |
| … | 2 | u2 | attributes_count | The number of the component’s attributes |
| … | varies | attribute_info[] | attributes | Signature, the annotation and the type annotation attributes |
The last four fields, a record_component_info, repeat for each
component. The source side is on the Java
records page.
PermittedSubclasses
On a sealed class or interface: the classes allowed to extend or implement it directly. The JVM turns down any other class that tries.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | number_of_classes | The number of entries |
| 8 | 2 × n | u2[] | classes | Class entries, one per permitted subclass |