Access flags are 16-bit masks, each bit a modifier or a property. Six places in a class file have them: the class itself, every field, every method, every entry of the InnerClasses attribute, every MethodParameters entry and the parts of a Module attribute. The same bit means different things in different places: 0x0020 is ACC_SUPER on a class but ACC_SYNCHRONIZED on a method, 0x0040 is ACC_VOLATILE on a field but ACC_BRIDGE on a method, and 0x0080 is ACC_TRANSIENT on a field but ACC_VARARGS on a method. Bits a table does not list are reserved; they should be zero and a JVM ignores them. The explorer shows each flags field as hexadecimal followed by the names of the bits that are set.
Class flags
In ClassFile.access_flags, after the constant pool.
| Flag | Value | Source | Meaning | From |
|---|---|---|---|---|
ACC_PUBLIC | 0x0001 | public | Usable from outside its package | 45.3 |
ACC_FINAL | 0x0010 | final | No subclasses allowed | 45.3 |
ACC_SUPER | 0x0020 | none | Use the modern meaning of invokespecial; treated as always set from Java SE 8 | 45.3 |
ACC_INTERFACE | 0x0200 | interface | An interface, not a class | 45.3 |
ACC_ABSTRACT | 0x0400 | abstract | Must not be instantiated | 45.3 |
ACC_SYNTHETIC | 0x1000 | none | Made by the compiler; not in the source | 49.0 |
ACC_ANNOTATION | 0x2000 | @interface | An annotation interface | 49.0 |
ACC_ENUM | 0x4000 | enum | An enum class | 49.0 |
ACC_MODULE | 0x8000 | module | A module declaration (module-info), not a class | 53.0 |
The rules on combining them:
- With ACC_INTERFACE, ACC_ABSTRACT must also be set, and ACC_FINAL, ACC_SUPER, ACC_ENUM and ACC_MODULE must not be.
- ACC_ANNOTATION needs ACC_INTERFACE.
- A class may not be both ACC_FINAL and ACC_ABSTRACT.
- With ACC_MODULE, no other flag may be set, and the file is a module-info: see modules.
A class file never has private, protected or
static flags, even for a nested class: a nested class is compiled to a
class file of its own, which is package-private or public, and its declared modifiers
are kept in the InnerClasses attribute.
ACC_SUPER. The JVM Specification explains that in JDK releases
before 1.0.2 the compiler wrote class flags in which this bit had no meaning, and the
JVM ignored it. Compilers from 1.0.2 set it, and the JVM then runs
invokespecial on a superclass method by looking it up from the direct
superclass. Since Java SE 8 the JVM treats the flag as set in every class file,
whatever the file says and whatever its version. This changed how old files run, not
how any file is laid out or read.
Field flags
In field_info.access_flags.
| Flag | Value | Source | Meaning | From |
|---|---|---|---|---|
ACC_PUBLIC | 0x0001 | public | Usable from anywhere | 45.3 |
ACC_PRIVATE | 0x0002 | private | Usable only within its class (and, from 55.0, its nest) | 45.3 |
ACC_PROTECTED | 0x0004 | protected | Usable from its package and subclasses | 45.3 |
ACC_STATIC | 0x0008 | static | One per class, not per object | 45.3 |
ACC_FINAL | 0x0010 | final | Never assigned after construction or class initialisation | 45.3 |
ACC_VOLATILE | 0x0040 | volatile | Cannot be cached; every read and write goes to memory in order | 45.3 |
ACC_TRANSIENT | 0x0080 | transient | Not written or read by a persistent object manager (serialisation) | 45.3 |
ACC_SYNTHETIC | 0x1000 | none | Made by the compiler, such as this$0, the outer object of an inner class | 49.0 |
ACC_ENUM | 0x4000 | none | One of an enum class’s constants | 49.0 |
- At most one of ACC_PUBLIC, ACC_PRIVATE and ACC_PROTECTED.
- Not both ACC_FINAL and ACC_VOLATILE.
- Every field of an interface must be ACC_PUBLIC, ACC_STATIC and ACC_FINAL; it may also be ACC_SYNTHETIC, and nothing else.
Method flags
In method_info.access_flags.
| Flag | Value | Source | Meaning | From |
|---|---|---|---|---|
ACC_PUBLIC | 0x0001 | public | Callable from anywhere | 45.3 |
ACC_PRIVATE | 0x0002 | private | Callable only within its class (and, from 55.0, its nest) | 45.3 |
ACC_PROTECTED | 0x0004 | protected | Callable from its package and subclasses | 45.3 |
ACC_STATIC | 0x0008 | static | No this; called with invokestatic | 45.3 |
ACC_FINAL | 0x0010 | final | Must not be overridden | 45.3 |
ACC_SYNCHRONIZED | 0x0020 | synchronized | The JVM takes the object’s (or class’s) monitor around the call | 45.3 |
ACC_BRIDGE | 0x0040 | none | A bridge method made by the compiler for generics or covariant returns | 49.0 |
ACC_VARARGS | 0x0080 | ... | The last parameter is a variable-arity array | 49.0 |
ACC_NATIVE | 0x0100 | native | Written in another language; no Code attribute | 45.3 |
ACC_ABSTRACT | 0x0400 | abstract | No implementation; no Code attribute | 45.3 |
ACC_STRICT | 0x0800 | strictfp | Floating point strictly to IEEE 754; only in versions 46 to 60 | 46.0 |
ACC_SYNTHETIC | 0x1000 | none | Made by the compiler, such as the lambda$main$0 body of a lambda | 49.0 |
- At most one of ACC_PUBLIC, ACC_PRIVATE and ACC_PROTECTED.
- An ACC_ABSTRACT method may not also be ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED or ACC_NATIVE, nor ACC_STRICT in versions 46 to 60.
- Interface methods: before 52.0 they must be ACC_PUBLIC and ACC_ABSTRACT. From 52.0 they must be ACC_PUBLIC or ACC_PRIVATE, and may not be ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED or ACC_NATIVE, so they may have bodies and may be static.
- A constructor (
<init>) may have at most one of the three access flags, plus ACC_VARARGS, ACC_STRICT and ACC_SYNTHETIC. - The class initialiser (
<clinit>) must be ACC_STATIC from 51.0; its other flags are ignored. Before 51.0 a method named<clinit>was taken as the initialiser whether or not it was ACC_STATIC.
ACC_STRICT. The specification says the value 0x0800 is
ACC_STRICT only in a class file whose major version is 46 to 60. From 61 (Java SE 17)
all floating point is strict, javac no longer sets the bit, and the JVM ignores it.
The explorer names the bit strict only in versions 46 to 60 and shows it
as an unnamed bit otherwise.
Nested class flags
In each entry of the InnerClasses
attribute, inner_class_access_flags keeps the modifiers the nested class
was declared with in the source, which its own class file cannot hold.
| Flag | Value | Source | Meaning |
|---|---|---|---|
ACC_PUBLIC | 0x0001 | public | Marked or implicitly public |
ACC_PRIVATE | 0x0002 | private | Marked private |
ACC_PROTECTED | 0x0004 | protected | Marked protected |
ACC_STATIC | 0x0008 | static | Marked or implicitly static: no outer object |
ACC_FINAL | 0x0010 | final | Marked or implicitly final |
ACC_INTERFACE | 0x0200 | interface | An interface |
ACC_ABSTRACT | 0x0400 | abstract | Marked or implicitly abstract |
ACC_SYNTHETIC | 0x1000 | none | Not in the source |
ACC_ANNOTATION | 0x2000 | @interface | An annotation interface |
ACC_ENUM | 0x4000 | enum | An enum class |
Parameter flags
In each entry of the MethodParameters attribute (52.0 and later).
| Flag | Value | Meaning |
|---|---|---|
ACC_FINAL | 0x0010 | Declared final |
ACC_SYNTHETIC | 0x1000 | Neither written in the source nor implied by the language: added by the compiler |
ACC_MANDATED | 0x8000 | Not written in the source but required by the language, such as the outer object passed to an inner class’s constructor |
Module flags
In the Module attribute of a module-info file (53.0 and later), three different flag fields.
| Field | Flag | Value | Meaning |
|---|---|---|---|
module_flags | ACC_OPEN | 0x0020 | An open module: every package is open to reflection |
module_flags | ACC_SYNTHETIC | 0x1000 | Not declared in the source |
module_flags | ACC_MANDATED | 0x8000 | Implicitly declared |
requires_flags | ACC_TRANSITIVE | 0x0020 | requires transitive: modules that read this one also read the required one |
requires_flags | ACC_STATIC_PHASE | 0x0040 | requires static: needed at compile time, optional at run time |
requires_flags | ACC_SYNTHETIC | 0x1000 | Not declared in the source |
requires_flags | ACC_MANDATED | 0x8000 | Implicitly declared, such as the dependency on java.base |
exports_flags, opens_flags | ACC_SYNTHETIC | 0x1000 | Not declared in the source |
exports_flags, opens_flags | ACC_MANDATED | 0x8000 | Implicitly declared |
Examples
| Bytes | Where | Flags | Source |
|---|---|---|---|
00 21 | class | ACC_PUBLIC, ACC_SUPER | public class Foo |
06 01 | class | ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT | public interface Foo |
40 31 | class | ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM | public enum Colour |
00 19 | field | ACC_PUBLIC, ACC_STATIC, ACC_FINAL | public static final int MAX |
00 09 | method | ACC_PUBLIC, ACC_STATIC | public static void main(String[] args) |
10 0A | method | ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC | the body of a lambda, such as lambda$main$0 |
How the source modifiers are written and what they mean is on the Java classes and interfaces pages.