Value Objects

Changes to the Java® Virtual Machine Specification • Version 21-internal-adhoc.dlsmith.20230428

This document describes changes to the Java Virtual Machine Specification, as modified by the Better-defined JVM Class File Validation JEP and JVM Types Cleanup, to support value objects, a preview feature introduced by a draft JEP.

A companion documents describes language changes.

Key changes include:

Changes are described with respect to existing sections of the JVM Specification. New text is indicated like this and deleted text is indicated like this. Explanation and discussion, as needed, is set aside in grey boxes.

Revision history:

Chapter 2: The Structure of the Java Virtual Machine

2.4 Reference Types and Values

There are three kinds of reference types: class types, array types, and interface types. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively.

Values of the reference types are either references to dynamically-allocated objects or the special null reference (representing the absence of an object).

An object is either a class instance or an array. Class instances encapsulate heterogeneously-typed instance fields, while arrays store a homogeneously-typed, fixed-length vector of components.

Some objects, called identity objects, are associated with a unique identity when they are created, distinguishing them from all other objects. An identity object may be an instance of an identity class, an instance of the class Object, or an array. These objects can mutate their instance fields or components and are associated with a synchronization monitor.

Other objects, called value objects, have no identity; the same object may be created multiple times, independently. A value object is always an instance of a value class. These objects have immutable instance fields and cannot be used for synchronization. A Java Virtual Machine implementation can sometimes inline a value object, avoiding the memory and indirection overhead usually associated with references.

A reference value typically belongs to multiple reference types, which may be either of the following:

A reference value may also be the special null reference, a reference to no object, which will be denoted here by null. The null reference initially has no run-time type, but may be cast to any type. The default value of a reference type is null.

This specification does not mandate a concrete value encoding null.

2.9 Special Methods

2.9.1 Instance Initialization Methods

A class has zero or more instance initialization methods, used to initialize instances of newly-allocated identity objects that belong to the class. Each typically corresponds to a constructor written in the Java programming language.

If a an identity class does not have an instance initialization method, its instances cannot be initialized or used.

An instance initialization method is declared with the special name <init>.

An instance initialization method may not be declared in a value class or an interface (4.6).

The declaration and use of an instance initialization method is constrained by the Java Virtual Machine. For the declaration, the method's access_flags item, descriptor, and code array are constrained (4.6, 4.9.2). For a use, an instance initialization method may be invoked only by the invokespecial instruction on an uninitialized class instance (4.9.1, 4.9.2).

Because the name <init> is not a valid identifier in the Java programming language, it cannot be used directly in a program written in the Java programming language.

2.9.4 value Class Instance Creation Methods

Design discussion: this section introduces a new kind of special method, a value class instance creation method, with its own special name, <vnew>. It follows the pattern of 2.9.1 and 2.9.2.

value class instance creation methods are intended as a compilation target for value class constructors, providing a standard API point for instance creation without language compilers needing to introduce an arbitrary (often mangled) name. The methods are invoked with invokestatic.

While there may be other uses for static factory methods with standardized names in the future, we anticipate that such a use would introduce a different special name, readily distinguishable and adhering to its own rules and conventions. It would be reasonable, for example, for a value class to declare both a class instance creation method and this alternative kind of factory method. The <foo> namespace remains reserved for any such future uses.

As an alternative naming scheme, we could re-use <init> but give the method a non-void return type. This would be convenient for tools that are happy to treat all constructor encodings similarly, but inconvenient for tools that need to distinguish between instance initialization <init> methods and value class instance creation <init> methods (see, for example, 4.10.1.9.invokespecial).

A non-abstract value class may declare zero or more value class instance creation methods. Each typically corresponds to a constructor written in the Java programming language. These methods return instances of the value class, created, for example, via the aconst_init and withfield instructions.

A value class instance creation method is declared with the special name <vnew>.

A value class instance creation method may not be declared in an identity class, an abstract class, or an interface (4.6).

The declaration and use of a value class instance creation method is constrained by the Java Virtual Machine. For the declaration, the method's access_flags item and descriptor are constrained (4.6). For a use, a value class instance creation method may be invoked only by the invokestatic instruction (4.9.1).

Because the name <vnew> is not a valid identifier in the Java programming language, it cannot be used directly in a program written in the Java programming language.

It may make sense to swap this new section with 2.9.3, with associated renumbering of cross references.

2.11 Instruction Set Summary

2.11.2 Load and Store Instructions

The load and store instructions transfer values between the local variables (2.6.1) and the operand stack (2.6.2) of a Java Virtual Machine frame (2.6):

Instructions that access fields of objects and elements of arrays (2.11.5) also transfer data to and from the operand stack.

Instruction mnemonics shown above with trailing letters between angle brackets (for instance, iload_<n>) denote families of instructions (with members iload_0, iload_1, iload_2, and iload_3 in the case of iload_<n>). Such families of instructions are specializations of an additional generic instruction (iload) that takes one operand. For the specialized instructions, the operand is implicit and does not need to be stored or fetched. The semantics are otherwise the same (iload_0 means the same thing as iload with the operand 0). The letter between the angle brackets specifies the type of the implicit operand for that family of instructions: for <n>, a nonnegative integer; for <i>, an int; for <l>, a long; for <f>, a float; and for <d>, a double.

This notation for instruction families is used throughout this specification.

2.11.5 Object Creation and Manipulation

Although both class instances and arrays are objects, the Java Virtual Machine creates and manipulates class instances and arrays using distinct sets of instructions:

Chapter 4: The class File Format

4.1 The ClassFile Structure

A class file consists of a single ClassFile structure:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items in the ClassFile structure are as follows:

magic

The magic item supplies the magic number identifying the class file format; it must have value 0xCAFEBABE.

minor_version, major_version

The values of the minor_version and major_version items are the minor and major version numbers of this class file. Together, a major and a minor version number determine the version of the class file format. If a class file has major version number M and minor version number m, we denote the version of its class file format as M.m.

A Java Virtual Machine implementation which conforms to Java SE N must support exactly the major versions of the class file format specified in the fourth column of Table 4.1-A, "Supported majors". The notation A .. B means major versions A through B, inclusive of both A and B. The third column, "Major", shows the major version introduced by each Java SE release, that is, the first release that could have accepted a class file containing that major_version item. For very early releases, the JDK version is shown instead of the Java SE release.

Table 4.1-A. class file format major versions

Java SE Released Major Supported majors
1.0.2 May 1996 45 45
1.1 February 1997 45 45
1.2 December 1998 46 45 .. 46
1.3 May 2000 47 45 .. 47
1.4 February 2002 48 45 .. 48
5.0 September 2004 49 45 .. 49
6 December 2006 50 45 .. 50
7 July 2011 51 45 .. 51
8 March 2014 52 45 .. 52
9 September 2017 53 45 .. 53
10 March 2018 54 45 .. 54
11 September 2018 55 45 .. 55
12 March 2019 56 45 .. 56
13 September 2019 57 45 .. 57
14 March 2020 58 45 .. 58
15 September 2020 59 45 .. 59
16 March 2021 60 45 .. 60

For a class file whose major_version is 56 or above, the minor_version must be 0 or 65535.

For a class file whose major_version is between 45 and 55 inclusive, the minor_version may be any value.

A historical perspective is warranted on JDK support for class file format versions. JDK 1.0.2 supported versions 45.0 through 45.3 inclusive. JDK 1.1 supported versions 45.0 through 45.65535 inclusive. When JDK 1.2 introduced support for major version 46, the only minor version supported under that major version was 0. Later JDKs continued the practice of introducing support for a new major version (47, 48, etc) but supporting only a minor version of 0 under the new major version. Finally, the introduction of preview features in Java SE 12 (see below) motivated a standard role for the minor version of the class file format, so JDK 12 supported minor versions of 0 and 65535 under major version 56. Subsequent JDKs introduce support for N.0 and N.65535 where N is the corresponding major version of the implemented Java SE Platform. For example, JDK 13 supports 57.0 and 57.65535.

The Java SE Platform may define preview features. A Java Virtual Machine implementation which conforms to Java SE N (N 12) must support all the preview features of Java SE N, and none of the preview features of any other Java SE release. The implementation must by default disable the supported preview features, and must provide a way to enable all of them, and must not provide a way to enable only some of them.

A class file is said to depend on the preview features of Java SE N (N 12) if it has a major_version that corresponds to Java SE N (according to Table 4.1-A) and a minor_version of 65535.

A class file must not depend on the preview features of Java SE N unless the Java Virtual Machine conforms to Java SE N and the preview features of Java SE N are enabled.

If the Java Virtual Machine conforms to some other version of Java SE, such as Java SE N+1, the class file is not valid.

A class file that does not depend on the preview features of any Java SE release is valid regardless of whether the preview features of Java SE N are enabled.

constant_pool_count

The value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one. A constant_pool index is considered valid if it is greater than zero and less than constant_pool_count, with the exception for constants of type long and double noted in 4.4.5.

constant_pool[]

The constant_pool is a table of structures (4.4) representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte.

The constant_pool table is indexed from 1 to constant_pool_count - 1.

access_flags

The value of the access_flags item is a mask of flags used to denote access permissions to and properties of this class or interface. The interpretation of each flag, when set, is specified in Table 4.1-B.

Table 4.1-B. Class access and property modifiers

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_IDENTITY 0x0020 Declared as an identity class or interface.
ACC_VALUE 0x0040 Declared as a value class or interface.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.
ACC_MODULE 0x8000 Is a module, not a class or interface.

In a class file with major version 53 or later, the ACC_MODULE flag indicates that this class file defines a module, not a class or interface. In a class file with major version less than 53, the 0x8000 bit is ignored, and the ACC_MODULE flag is considered not to be set. If the ACC_MODULE flag is set, then no other flag in Table 4.1-B may be set.

The ACC_INTERFACE flag indicates that this class file defines an interface, not a module or class. If the ACC_INTERFACE flag is set, the ACC_ABSTRACT flag must also be set, and the ACC_FINAL, ACC_ENUM, and ACC_MODULE flags must not be set.

If neither the ACC_INTERFACE flag nor the ACC_MODULE flag is set, this class file defines a class, not a module or interface. In this case, any of the other flags in Table 4.1-B may be set except ACC_ANNOTATION.

The ACC_FINAL flag indicates that this class cannot be extended by another class. If the ACC_FINAL flag is set, the ACC_ABSTRACT flag must not be set.

In a class file with version number 61.65535, the ACC_IDENTITY flag indicates that this class or interface is an identity class or an identity interface. For such a class or interface, all instances (of a class directly or of any subclasses) are identity objects (2.4). In a class file with any other version number, the 0x0020 bit is ignored; if the class file defines a class, the ACC_IDENTITY flag is considered to be set, and otherwise the ACC_IDENTITY flag is considered not to be set.

Thus, all classes declared with version numbers other than 61.65535 are identity classes. Interfaces, on the other hand, by default are neither identity interfaces nor value interfaces.

Historically, the value 0x0020 was used to indicate ACC_SUPER, which affected the semantics of any invokespecial instructions (6.5.invokespecial) appearing in the class. In Java SE 8, the ACC_SUPER semantics became mandatory, regardless of the setting of ACC_SUPER or the class file version number, and the flag no longer had any effect. Now the flag has been repurposed as ACC_IDENTITY.

In a class file with version number 61.65535, the ACC_VALUE flag indicates that this class is a value class or a value interface. For such a class or interface, all instances (of a class directly or of any subclasses) are value objects (2.4). In a class file with any other version number, the 0x0040 bit is ignored, and the ACC_VALUE flag is considered not to be set.

If the ACC_VALUE flag is set, one of the ACC_FINAL or ACC_ABSTRACT flags must also be set.

The value 0x0040 is interpreted as ACC_VOLATILE when applied to a field, and as ACC_BRIDGE when applied to a method.

A ClassFile structure must have no more than one of its ACC_IDENTITY and ACC_VALUE flags set.

A class or interface may have neither its ACC_IDENTITY flag nor its ACC_VALUE flag set. Such a class or interface may be extended or implemented by both kinds of classes. Value object instances will be created without executing any instance initialization method of the class (2.9.1).

If a class other than java/lang/Object has neither its ACC_IDENTITY flag nor its ACC_VALUE flag set, then its ACC_ABSTRACT flag must be set.

The Object class is unique in that identity object instances of the class may be created via new (6.5.new) even though the class is not declared an identity class. This special treatment allows the class to be extended by value classes.

The ACC_SYNTHETIC flag indicates that this class or interface was generated by a compiler and does not appear in source code.

The ACC_ANNOTATION flag indicates that this interface is declared as an annotation interface (JLS §9.6). If the ACC_ANNOTATION flag is set, the ACC_INTERFACE flag must also be set.

The ACC_ENUM flag indicates that this class or its superclass is declared as an enum class (JLS §8.9).

All bits of the access_flags item not assigned in Table 4.1-B are reserved for future use. They should be set to zero in generated class files and are ignored by Java Virtual Machine implementations.

Historically, the value 0x0020 was used to indicate ACC_SUPER, which affected the semantics of any invokespecial instructions (6.5.invokespecial) appearing in the class or interface. In Java SE 8, the ACC_SUPER semantics became mandatory, regardless of the setting of ACC_SUPER or the class file version number, and the flag no longer had any effect.

this_class

The value of the this_class item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) referencing a class or interface name.

For a module, the referenced name must be module-info.

For a class or interface, the this_class item represents the class or interface defined by this class file.

super_class

For a module or a class named java/lang/Object, the value of the super_class item must be 0.

For a class with any other name, the value of the super_class item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure referencing a class or interface name.

For an interface, the value of the super_class item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure referencing the name java/lang/Object.

The super_class item represents the direct superclass of the class or interface defined by this class file.

The class Object has no direct superclass. Interfaces effectively have Object as their direct superclass.

interfaces_count

The value of the interfaces_count item gives the number of direct superinterfaces of this class or interface.

For a module, interfaces_count must be 0.

interfaces[]

Each value in the interfaces array must be a valid index into the constant_pool table. The constant_pool entry at each value of interfaces[i], where 0 i < interfaces_count, must be a CONSTANT_Class_info structure referencing a class or interface name.

The interfaces array represents each interface that is a direct superinterface of this class or interface, in the left-to-right order given in the source for the class or interface.

fields_count

The value of the fields_count item gives the number of field_info structures in the fields table. The field_info structures represent all fields, both class variables and instance variables, declared by this class or interface.

For a module, fields_count must be 0.

fields[]

Each value in the fields table must be a field_info structure (4.5) giving a complete description of a field in this class or interface. The fields table includes only those fields that are declared by this class or interface. It does not include items representing fields that are inherited from superclasses or superinterfaces.

methods_count

The value of the methods_count item gives the number of method_info structures in the methods table.

For a module, methods_count must be 0.

methods[]

Each value in the methods table must be a method_info structure (4.6) giving a complete description of a method in this class or interface.

The method_info structures represent all methods declared by this class or interface, including instance methods, class methods, instance initialization methods (2.9.1), and any class or interface initialization method (2.9.2). The methods table does not include items representing methods that are inherited from superclasses or superinterfaces.

attributes_count

The value of the attributes_count item gives the number of attributes in the attributes table of this class.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

The attributes defined by this specification as appearing in the attributes table of a ClassFile structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a ClassFile structure are given in 4.7.

The rules concerning nonstandard attributes in the attributes table of a ClassFile structure are given in 4.7.1.

4.2 Names

4.2.2 Unqualified Names

Names of methods, fields, local variables, and formal parameters are stored as unqualified names. An unqualified name must contain at least one Unicode code point and must not contain any of the ASCII characters . ; [ / (that is, period or semicolon or left square bracket or forward slash).

Method names are further constrained so that, with the exception of the special method names <init>, and <clinit>, and <vnew> (2.9), they must not contain the ASCII characters < or > (that is, left angle bracket or right angle bracket).

4.4 The Constant Pool

4.4.8 The CONSTANT_MethodHandle_info Structure

Design discussion: the withfield and aconst_init instructions may justify new forms of CONSTANT_MethodHandle, but for now no changes are made to reference_kind.

The CONSTANT_MethodHandle_info structure is used to represent a method handle:

CONSTANT_MethodHandle_info {
    u1 tag;
    u1 reference_kind;
    u2 reference_index;
}

The items of the CONSTANT_MethodHandle_info structure are the following:

tag

The tag item has the value CONSTANT_MethodHandle (15).

reference_kind

The value of the reference_kind item must be in the range 1 to 9. The value denotes the kind of this method handle, which characterizes its bytecode behavior (5.4.3.5).

reference_index

The value of the reference_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be as follows:

  • If the value of the reference_kind item is 1 (REF_getField), 2 (REF_getStatic), 3 (REF_putField), or 4 (REF_putStatic), then the constant_pool entry at that index must be a CONSTANT_Fieldref_info structure (4.4.2).

    The reference_index item represents a field for which a method handle is to be created.

  • If the value of the reference_kind item is 5 (REF_invokeVirtual) or 8 (REF_newInvokeSpecial), then the constant_pool entry at that index must be a CONSTANT_Methodref_info structure (4.4.2).

    The reference_index item represents a class's method or constructor (2.9.1) for which a method handle is to be created.

  • If the value of the reference_kind item is 6 (REF_invokeStatic) or 7 (REF_invokeSpecial), then if the class file version number is less than 52.0, the constant_pool entry at that index must be a CONSTANT_Methodref_info structure; if the class file version number is 52.0 or above, the constant_pool entry at that index must be either a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure (4.4.2).

    The reference_index item represents a class's or interface's method for which a method handle is to be created.

  • If the value of the reference_kind item is 9 (REF_invokeInterface), then the constant_pool entry at that index must be a CONSTANT_InterfaceMethodref_info structure.

    The reference_index item represents an interface's method for which a method handle is to be created.

If the value of the reference_kind item is 5 (REF_invokeVirtual), 6 (REF_invokeStatic), 7 (REF_invokeSpecial), or 9 (REF_invokeInterface), the name of the method represented by a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure must not be <init> or <vnew>.

If the value of the reference_kind item is 6 (REF_invokeStatic), the name of the method represented by a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure must not be <init>.

If the value is 8 (REF_newInvokeSpecial), the name of the method represented by a CONSTANT_Methodref_info structure must be <init>.

In no case may the name be <clinit>, because Methodref and InterfaceMethodref structures that reference that name are already prohibited (4.4.2).

4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures

Most structures in the constant_pool table represent entities directly, by combining names, descriptors, and values recorded statically in the table. In contrast, the CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info structures represent entities indirectly, by pointing to code which computes an entity dynamically. The code, called a bootstrap method, is invoked by the Java Virtual Machine during resolution of symbolic references derived from these structures (5.1, 5.4.3.6). Each structure specifies a bootstrap method as well as an auxiliary name and type that characterize the entity to be computed. In more detail:

CONSTANT_Dynamic_info {
    u1 tag;
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
}

CONSTANT_InvokeDynamic_info {
    u1 tag;
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
}

The items of these structures are as follows:

tag

The tag item of a CONSTANT_Dynamic_info structure has the value CONSTANT_Dynamic (17).

The tag item of a CONSTANT_InvokeDynamic_info structure has the value CONSTANT_InvokeDynamic (18).

bootstrap_method_attr_index

The value of the bootstrap_method_attr_index item must be a valid index into the bootstrap_methods table of the BootstrapMethods attribute of this ClassFile structure (4.7.23).

CONSTANT_Dynamic_info structures are unique in that they are syntactically allowed to refer to themselves via the bootstrap method table. Rather than mandating that such cycles are detected when classes are loaded (a potentially expensive check), we permit cycles initially but mandate a failure at resolution (5.4.3.6).

name_and_type_index

The value of the name_and_type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (4.4.6). This constant_pool entry indicates a name and descriptor.

In a CONSTANT_Dynamic_info structure, the indicated descriptor must be a field descriptor (4.3.2).

In a CONSTANT_InvokeDynamic_info structure, the indicated name must be a valid method name (4.2.2) and must not be <clinit>, or <init>, or <vnew>. The indicated descriptor must be a method descriptor (4.3.3).

We could allow <vnew> here, but the precedent seems to be to avoid any special method names when using invokedynamic.

4.5 Fields

Each field is described by a field_info structure.

A ClassFile structure must not declare two fields with the same name and descriptor (4.3.2).

The structure has the following format:

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the field_info structure are as follows:

access_flags

The value of the access_flags item is a mask of flags used to denote access permission to and properties of this field. The interpretation of each flag, when set, is specified in Table 4.5-A.

Table 4.5-A. Field access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_PRIVATE 0x0002 Declared private; accessible only within the defining class and other classes belonging to the same nest (5.4.4).
ACC_PROTECTED 0x0004 Declared protected; may be accessed within subclasses.
ACC_STATIC 0x0008 Declared static.
ACC_FINAL 0x0010 Declared final; never directly assigned to after object construction (JLS §17.5).
ACC_VOLATILE 0x0040 Declared volatile; cannot be cached.
ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent object manager.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ENUM 0x4000 Declared as an element of an enum class.

Fields of classes may set any of the flags in Table 4.5-A. However, each field of a class must have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS §8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS §8.3.1.4).

In an abstract class that is not an identity class, each field must have its ACC_STATIC flag set.

In a non-abstract value class, each field must have at least one of its ACC_STATIC or ACC_FINAL flags set.

Fields of interfaces must have their ACC_PUBLIC, ACC_STATIC, and ACC_FINAL flags set; they may have their ACC_SYNTHETIC flag set and must not have any of the other flags in Table 4.5-A set (JLS §9.3).

The ACC_SYNTHETIC flag indicates that this field was generated by a compiler and does not appear in source code.

The ACC_ENUM flag indicates that this field is used to hold an element of an enum class (JLS §8.9).

All bits of the access_flags item not assigned in Table 4.5-A are reserved for future use. They should be set to zero in generated class files and are ignored by Java Virtual Machine implementations.

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) which represents a valid unqualified name (4.2.2).

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) which represents a valid field descriptor (4.3.2).

attributes_count

The value of the attributes_count item indicates the number of additional attributes of this field.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

The attributes defined by this specification as appearing in the attributes table of a field_info structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a field_info structure are given in 4.7.

The rules concerning nonstandard attributes in the attributes table of a field_info structure are given in 4.7.1.

4.6 Methods

Each method, including each instance initialization method (2.9.1) and the class or interface initialization method (2.9.2), is described by a method_info structure.

A ClassFile structure must not declare two methods with the same name and descriptor (4.3.3).

The structure has the following format:

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the method_info structure are as follows:

access_flags

The value of the access_flags item is a mask of flags used to denote access permission to and properties of this method. The interpretation of each flag, when set, is specified in Table 4.6-A.

Table 4.6-A. Method access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_PRIVATE 0x0002 Declared private; accessible only within the defining class and other classes belonging to the same nest (5.4.4).
ACC_PROTECTED 0x0004 Declared protected; may be accessed within subclasses.
ACC_STATIC 0x0008 Declared static.
ACC_FINAL 0x0010 Declared final; must not be overridden (5.4.5).
ACC_SYNCHRONIZED 0x0020 Declared synchronized; invocation is wrapped by a monitor use.
ACC_BRIDGE 0x0040 A bridge method, generated by the compiler.
ACC_VARARGS 0x0080 Declared with variable number of arguments.
ACC_NATIVE 0x0100 Declared native; implemented in a language other than the Java programming language.
ACC_ABSTRACT 0x0400 Declared abstract; no implementation is provided.
ACC_STRICT 0x0800 Declared strictfp; floating-point mode is FP-strict.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.

A method named <init> (2.9.1) must have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set, and may also have its ACC_VARARGS, ACC_STRICT, and ACC_SYNTHETIC flags set, but must not have any of the other flags in Table 4.6-A set.

A method named <clinit> (2.9.2) may have any of the flags in Table 4.6-A set, in any combination, but all flags except ACC_STATIC, ACC_STRICT, and ACC_SYNTHETIC are treated by the Java Virtual Machine as if they were not set. In a class file whose version number is 51.0 or greater, the ACC_STATIC flag must be set; in a class file whose version number is less than 51.0, the ACC_STATIC flag is treated by the Java Virtual Machine as if it were set.

A method named <vnew> (2.9.3) must have its ACC_STATIC flag set, must not have its ACC_ABSTRACT flag set, must have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set, and may have any of the other flags in Table 4.6-A set.

Methods of classes with names other than <init>, and <clinit>, and <vnew> may have any of the flags in Table 4.6-A set. However, each such method must have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS §8.4.3).

In a class that is not an identity class, a method that has its ACC_SYNCHRONIZED flag set must also have its ACC_STATIC flag set.

Methods of interfaces with names other than <clinit> must not have their ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE flags set (JLS §9.4); exactly one of the ACC_PUBLIC or ACC_PRIVATE flags must be set. They may have any of the other flags in Table 4.6-A set. In a class file whose version number is less than 52.0, each method of an interface with a name other than <clinit> must have its ACC_PUBLIC and ACC_ABSTRACT flags set.

If a method of a class or interface has its ACC_ABSTRACT flag set, it must not have any of its ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, or ACC_STRICT flags set.

The ACC_BRIDGE flag is used to indicate a bridge method generated by a compiler for the Java programming language.

The ACC_VARARGS flag indicates that this method takes a variable number of arguments at the source code level.

The ACC_SYNTHETIC flag indicates that this method was generated by a compiler and does not appear in source code, and is not one of the methods named in 4.7.8.

All bits of the access_flags item not assigned in Table 4.6-A are reserved for future use. They should be set to zero in generated class files and are ignored by Java Virtual Machine implementations.

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a valid unqualified method name.

A method of a value class or an interface must not have the name <init>.

A method of an abstract class, an identity class, or an interface must not have the name <vnew>.

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing a valid method descriptor (4.3.3). Furthermore:

  • If the name of the method is <init>, then the descriptor must denote a void method.

  • If the name of the method is <clinit>, then the descriptor must denote a void method that takes no arguments.

  • If the name of the method is <vnew>, then the descriptor must denote a return type that is the type of the current class or interface.

A future edition of this specification may require that the last parameter descriptor of the method descriptor is an array type if the ACC_VARARGS flag is set in the access_flags item.

A hidden class is incapable of naming its class type in a descriptor. Rather than declaring a <vnew> method, a hidden value class will have to provide a different instance creation mechanism—for example, a static method named $make.

attributes_count

The value of the attributes_count item indicates the number of additional attributes of this method.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

The attributes defined by this specification as appearing in the attributes table of a method_info structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a method_info structure are given in 4.7.

The rules concerning nonstandard attributes in the attributes table of a method_info structure are given in 4.7.1.

4.7 Attributes

Attributes are used in the ClassFile, field_info, method_info, Code_attribute, and record_component_info structures of the class file format (4.1, 4.5, 4.6, 4.7.3, 4.7.30).

All attributes have the following general format:

attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}

For all attributes, the attribute_name_index item must be a valid unsigned 16-bit index into the constant pool of the class. The constant_pool entry at attribute_name_index must be a CONSTANT_Utf8_info structure (4.4.7) which represents the name of the attribute. The value of the attribute_length item indicates the length of the subsequent information in bytes. The length does not include the initial six bytes that contain the attribute_name_index and attribute_length items.

29 30 attributes are predefined by this specification. They are listed three times, for ease of navigation:

Within the context of their use in this specification, that is, in the attributes tables of the structures of appropriately-versioned class files in which they appear, the names of these predefined attributes are reserved.

Any conditions on the presence of a predefined attribute in an attributes table are specified explicitly in the section which describes the attribute. If no conditions are specified, then the attribute may appear any number of times in an attributes table.

The predefined attributes are categorized into two groups according to their purpose:

  1. Nine attributes are critical to correct interpretation of the class file by the Java Virtual Machine:

    • ConstantValue
    • Code
    • StackMapTable
    • BootstrapMethods
    • Module
    • ModulePackages
    • ModuleMainClass
    • NestHost
    • NestMembers

    In a class file whose version number is v, each of these attributes must be recognized and correctly read by an implementation of the Java Virtual Machine if the implementation supports version v of the class file format, and the attribute was first defined in version v or earlier of the class file format, and the attribute appears in a location where it is defined to appear.

  2. 20 21 attributes are not critical to correct interpretation of the class file by the Java Virtual Machine, but contain metadata about the class file that is either exposed by the class libraries of the Java SE Platform, or made available by tools (in which case the section that specifies an attribute describes it as "optional"):

    • Exceptions
    • InnerClasses
    • EnclosingMethod
    • Synthetic
    • Signature
    • Record
    • SourceFile
    • SourceDebugExtension
    • LineNumberTable
    • LocalVariableTable
    • LocalVariableTypeTable
    • Deprecated
    • RuntimeVisibleAnnotations
    • RuntimeInvisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • RuntimeInvisibleTypeAnnotations
    • AnnotationDefault
    • MethodParameters
    • Preload

    An implementation of the Java Virtual Machine may use the information that these attributes contain, or otherwise must silently ignore these attributes.

Table 4.7-A. Predefined class file attributes (by section)

Attribute Section class file Java SE
ConstantValue 4.7.2 45.3 1.0.2
Code 4.7.3 45.3 1.0.2
StackMapTable 4.7.4 50.0 6
Exceptions 4.7.5 45.3 1.0.2
InnerClasses 4.7.6 45.3 1.1
EnclosingMethod 4.7.7 49.0 5.0
Synthetic 4.7.8 45.3 1.1
Signature 4.7.9 49.0 5.0
SourceFile 4.7.10 45.3 1.0.2
SourceDebugExtension 4.7.11 49.0 5.0
LineNumberTable 4.7.12 45.3 1.0.2
LocalVariableTable 4.7.13 45.3 1.0.2
LocalVariableTypeTable 4.7.14 49.0 5.0
Deprecated 4.7.15 45.3 1.1
RuntimeVisibleAnnotations 4.7.16 49.0 5.0
RuntimeInvisibleAnnotations 4.7.17 49.0 5.0
RuntimeVisibleParameterAnnotations 4.7.18 49.0 5.0
RuntimeInvisibleParameterAnnotations 4.7.19 49.0 5.0
RuntimeVisibleTypeAnnotations 4.7.20 52.0 8
RuntimeInvisibleTypeAnnotations 4.7.21 52.0 8
AnnotationDefault 4.7.22 49.0 5.0
BootstrapMethods 4.7.23 51.0 7
MethodParameters 4.7.24 52.0 8
Module 4.7.25 53.0 9
ModulePackages 4.7.26 53.0 9
ModuleMainClass 4.7.27 53.0 9
NestHost 4.7.28 55.0 11
NestMembers 4.7.29 55.0 11
Record 4.7.30 60.0 16
Preload 4.7.31 61.65535 18

Table 4.7-B. Predefined class file attributes (by class file format)

Attribute class file Java SE Section
ConstantValue 45.3 1.0.2 4.7.2
Code 45.3 1.0.2 4.7.3
Exceptions 45.3 1.0.2 4.7.5
SourceFile 45.3 1.0.2 4.7.10
LineNumberTable 45.3 1.0.2 4.7.12
LocalVariableTable 45.3 1.0.2 4.7.13
InnerClasses 45.3 1.1 4.7.6
Synthetic 45.3 1.1 4.7.8
Deprecated 45.3 1.1 4.7.15
EnclosingMethod 49.0 5.0 4.7.7
Signature 49.0 5.0 4.7.9
SourceDebugExtension 49.0 5.0 4.7.11
LocalVariableTypeTable 49.0 5.0 4.7.14
RuntimeVisibleAnnotations 49.0 5.0 4.7.16
RuntimeInvisibleAnnotations 49.0 5.0 4.7.17
RuntimeVisibleParameterAnnotations 49.0 5.0 4.7.18
RuntimeInvisibleParameterAnnotations 49.0 5.0 4.7.19
AnnotationDefault 49.0 5.0 4.7.22
StackMapTable 50.0 6 4.7.4
BootstrapMethods 51.0 7 4.7.23
RuntimeVisibleTypeAnnotations 52.0 8 4.7.20
RuntimeInvisibleTypeAnnotations 52.0 8 4.7.21
MethodParameters 52.0 8 4.7.24
Module 53.0 9 4.7.25
ModulePackages 53.0 9 4.7.26
ModuleMainClass 53.0 9 4.7.27
NestHost 55.0 11 4.7.28
NestMembers 55.0 11 4.7.29
Record 60.0 16 4.7.30
Preload 61.65535 18 4.7.31

Table 4.7-C. Predefined class file attributes (by location)

Attribute Location class file
SourceFile ClassFile 45.3
InnerClasses ClassFile 45.3
EnclosingMethod ClassFile 49.0
SourceDebugExtension ClassFile 49.0
BootstrapMethods ClassFile 51.0
Module, ModulePackages, ModuleMainClass ClassFile 53.0
NestHost, NestMembers ClassFile 55.0
Record ClassFile 60.0
ConstantValue field_info 45.3
Code method_info 45.3
Exceptions method_info 45.3
RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations method_info 49.0
AnnotationDefault method_info 49.0
MethodParameters method_info 52.0

Table 4.7-C (cont.). Predefined class file attributes (by location)

Attribute Location class file
Synthetic ClassFile, field_info, method_info 45.3
Deprecated ClassFile, field_info, method_info 45.3
Signature ClassFile, field_info, method_info, record_component_info 49.0
Preload ClassFile 61.65535
RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations ClassFile, field_info, method_info, record_component_info 49.0
LineNumberTable Code 45.3
LocalVariableTable Code 45.3
LocalVariableTypeTable Code 49.0
StackMapTable Code 50.0
RuntimeVisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations ClassFile, field_info, method_info, Code, record_component_info 52.0

4.7.6 The InnerClasses Attribute

...

inner_class_access_flags

The value of the inner_class_access_flags item is a mask of flags used to denote access permissions to and properties of class or interface C as declared in the source code from which this class file was compiled. It is used by a compiler to recover the original information when source code is not available. The flags are specified in Table 4.7.6-A.

Table 4.7.6-A. Nested class access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Marked or implicitly public in source.
ACC_PRIVATE 0x0002 Marked private in source.
ACC_PROTECTED 0x0004 Marked protected in source.
ACC_STATIC 0x0008 Marked or implicitly static in source.
ACC_FINAL 0x0010 Marked or implicitly final in source.
ACC_IDENTITY 0x0020 Declared as an identity class or interface.
ACC_VALUE 0x0040 Declared as a value class or interface.
ACC_INTERFACE 0x0200 Was an interface in source.
ACC_ABSTRACT 0x0400 Marked or implicitly abstract in source.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation interface.
ACC_ENUM 0x4000 Declared as an enum class.

All bits of the inner_class_access_flags item not assigned in Table 4.7.6-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

...

4.7.31 The Preload Attribute

The Preload attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1) in a version 61.65535 class file. The Preload attribute indicates to a Java Virtual Machine implementation that certain classes contain information that may be of interest during linkage. For example, a value class might be listed to facilitate inlining of value objects.

There must be no more than one Preload attribute in the attributes table of a ClassFile structure.

The Preload attribute should have the following format:

Preload_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_classes;
    u2 classes[number_of_classes];
}

The items of the Preload_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item is an index into the constant_pool table. The constant_pool entry at that index is a CONSTANT_Utf8_info structure (4.4.7) representing the string "Preload".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

number_of_classes

The value of the number_of_classes item indicates the number of entries in the classes array.

classes[]

Each value in the classes array should be a valid index into the constant_pool table. The constant_pool entry at that index should be a CONSTANT_Class_info structure (4.4.1) representing a class or interface.

4.9 Constraints on Java Virtual Machine Code

4.9.1 Static Constraints

The static constraints on the code in a class file specify how Java Virtual Machine instructions must be laid out in the code array, what the operands of individual instructions must be, and how exception_table and StackMapTable entries reference the code array and the constant pool.

The static constraints on the instructions in the code array are as follows:

The static constraints on the operands of instructions in the code array are as follows:

The static constraints on the entries in the exception_table array are as follows:

The static constraints on the entries in the the entries table of a StackMapTable attribute (4.7.4) are as follows:

4.9.2 Structural Constraints

The structural constraints on the code in a class file specify constraints on relationships between Java Virtual Machine instructions, exception handlers, and stack maps. The structural constraints are as follows:

4.10 Verification of class Files

4.10.1 Verification by Type Checking

4.10.1.9 Type Checking Instructions
aconst_init

An aconst_init instruction with operand CP is type safe iff one can validly push type CP onto the incoming operand stack yielding the outgoing type state.

instructionIsTypeSafe(aconst_init(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    validTypeTransition(Environment, [], CP, StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
withfield

A withfield instruction with operand CP is type safe iff its operand, CP, refers to a constant pool entry denoting a field whose declared type is FieldType, as a member of type FieldClassType; and one can validly replace types matching FieldType and FieldClassType with FieldClassType on the incoming operand stack, yielding the outgoing type state.

instructionIsTypeSafe(withfield(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    CP = field(FieldClassType, _FieldName, FieldDescriptor),
    parseFieldDescriptor(FieldDescriptor, FieldType),
    validTypeTransition(Environment, [FieldType, FieldClassType],
                        FieldClassType, StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).

Chapter 5: Loading, Linking, and Initializing

5.3 Creation and Loading

5.3.5 Deriving a Class from a class File Representation

The following steps are used to derive a Class object for the nonarray class or interface C denoted by N using loader L from a purported representation in class file format.

  1. First, the Java Virtual Machine determines whether the attempt to derive a class or interface named N for class loader L is invalid. If so, loading throws a LinkageError.

    An attempt to derive a class or interface named N for class loader L is invalid if one of the following are true:

    • L has already been recorded as as an initiating loader of a class or interface named N.

    • L is not the bootstrap class loader (5.3) and N is the reserved name java/lang/Object.

    The second case, combined with restrictions in 4.1, ensures that there is only one root of the class hierarchy, and the name java/lang/Object can reliably be used to refer to it.

    The Java SE API enforces additional security restrictions that prevent unauthorized attempts to load classes in certain packages, including java.*.

  2. Otherwise, the Java Virtual Machine attempts to parse the purported representation. However, the purported representation may not in fact be a valid representation of C.

    This phase of loading must detect the following errors:

    • If the purported representation provides a major and minor version number in its 5th through 8th bytes (4.1), but the version number is not supported by this Java Virtual Machine implementation, loading throws an instance of UnsupportedClassVersionError.

      UnsupportedClassVersionError, a subclass of ClassFormatError, was introduced to enable easy identification of a ClassFormatError caused by an attempt to load a class whose representation uses an unsupported version of the class file format. In JDK 1.1 and earlier, an instance of NoClassDefFoundError or ClassFormatError was thrown in case of an unsupported version, depending on whether the class was being loaded by the system class loader or a user-defined class loader.

    • Otherwise, if the purported representation is not a valid class file ([4]), loading throws an instance of ClassFormatError.

    • Otherwise, if the purported representation does not actually represent a class or interface named N, loading throws an instance of NoClassDefFoundError or an instance of one of its subclasses.

      This occurs when the purported representation has either a this_class item which specifies a name other than N, or an access_flags item which has the ACC_MODULE flag set.

  3. If C has a direct superclass, the symbolic reference from C to its direct superclass is resolved using the algorithm of 5.4.3.1. Only Object has no direct superclass.

    Note that if C is an interface, its direct superclass is the class Object (4.1). The symbolic reference to Object is resolved just like a reference to any other class.

    Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:

    • If any of the superclasses of C is C itself, loading throws a ClassCircularityError.

    • Otherwise, if the class or interface named as the direct superclass of C is in fact an interface or a final class, loading throws an IncompatibleClassChangeError.

    • Otherwise, if C is an identity class and any superclass of C is a value class, or C is a value class and any superclass of C is an identity class, loading throws an IncompatibleClassChangeError.

    • Otherwise, if C is a class and some instance method declared in C can override (5.4.5) a final instance method declared in a superclass of C, loading throws an IncompatibleClassChangeError.

  4. If C has any direct superinterfaces, the symbolic references from C to its direct superinterfaces are resolved using the algorithm of 5.4.3.1.

    Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:

    • If any of the superinterfaces of C is C itself, loading throws a ClassCircularityError.

    • Otherwise, if any of the classes or interfaces named as direct superinterfaces of C is not in fact an interface, loading throws an IncompatibleClassChangeError.

    • Otherwise, if C, one of its superclasses, or one of its superinterfaces is an identity class or an identity interface, and some other of C, one of its superclasses, or one of its superinterfaces is a value class or a value interface, loading throws an IncompatibleClassChangeError.

  5. The Java Virtual Machine marks C as having L as its defining class loader and records that L is an initiating loader of C (5.3.4).

5.4 Linking

5.4.3 Resolution

Many Java Virtual Machine instructions - aconst_init, anewarray, checkcast, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, ldc2_w, multianewarray, new, putfield, and putstatic, and withfield - rely on symbolic references in the run-time constant pool. Execution of any of these instructions requires resolution of the symbolic reference.

...

5.5 Initialization

Initialization of a class or interface consists of executing its class or interface initialization method (2.9.2).

A class or interface C may be initialized only as a result of:

Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.

Because the Java Virtual Machine is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface. The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization by using the following procedure. It assumes that the class or interface has already been verified and prepared, and that the class or interface contains state that indicates one of four situations:

For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. For example, LC could be the Class object for C, or the monitor associated with that Class object. The procedure for initializing C is then as follows:

  1. Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

  2. If C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this procedure.

    Thread interrupt status is unaffected by execution of the initialization procedure.

  3. If C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

  4. If C indicates that it has already been initialized, then no further action is required. Release LC and complete normally.

  5. If C is in an erroneous state, then initialization is not possible. Release LC and throw a NoClassDefFoundError.

  6. Otherwise, record the fact that initialization of the Class object for C is in progress by the current thread, and release LC.

    Then, initialize each final static field of C with the constant value in its ConstantValue attribute (4.7.2), in the order the fields appear in the ClassFile structure.

  7. Next, if C is a class rather than an interface, then let SC be its superclass and let SI1, ..., SIn be all superinterfaces of C (whether direct or indirect) that declare at least one non-abstract, non-static method. The order of superinterfaces is given by a recursive enumeration over the superinterface hierarchy of each interface directly implemented by C. For each interface I directly implemented by C (in the order of the interfaces array of C), the enumeration recurs on I's superinterfaces (in the order of the interfaces array of I) before returning I.

    For each S in the list [ SC, SI1, ..., SIn ], if S has not yet been initialized, then recursively perform this entire procedure for S. If necessary, verify and prepare S first.

    If the initialization of S completes abruptly because of a thrown exception, then acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing S.

  8. Next, determine whether assertions are enabled for C by querying its defining class loader.

  9. Next, if C declares a class or interface initialization method, execute that method.

  10. If the execution of the class or interface initialization method completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.

  11. Otherwise, the class or interface initialization method must have completed abruptly by throwing some exception E. If the class of E is not Error or one of its subclasses, then create a new instance of the class ExceptionInInitializerError with E as the argument, and use this object in place of E in the following step. If a new instance of ExceptionInInitializerError cannot be created because an OutOfMemoryError occurs, then use an OutOfMemoryError object in place of E in the following step.

  12. Acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete this procedure abruptly with reason E or its replacement as determined in the previous step.

A Java Virtual Machine implementation may optimize this procedure by eliding the lock acquisition in step 1 (and release in step 4/5) when it can determine that the initialization of the class has already completed, provided that, in terms of the Java memory model, all happens-before orderings (JLS §17.4.5) that would exist if the lock were acquired, still exist when the optimization is performed.

Chapter 6: The Java Virtual Machine Instruction Set

6.5 Instructions

aconst_init

Operation

Push initial instance of a value class

Format

aconst_init
indexbyte1
indexbyte2

Forms

aconst_init = 203 (0xcb)

Operand Stack

...

..., objectref

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class or interface.

The referenced class or interface is resolved (5.4.3.1). The resolved class or interface must be a value class that belongs to the same nest as the current class, according to the nestmate test in 5.4.4.

The referenced value class is initialized if it has not already been initialized (5.5).

A reference to an instance of the value class, with instance variable values set to the default initial values of their types (2.3, 2.4), is pushed onto the operand stack. Memory for the class instance may be newly allocated from the garbage-collected heap, or may have been allocated previously.

Linking Exceptions

During resolution of the symbolic reference to the class or interface, any of the exceptions documented in 5.4.3.1 can be thrown.

If the referenced class or interface is abstract or is not a value class, aconst_init fails with an IncompatibleClassChangeError.

Otherwise, if the referenced value class does not belong to the same nest as the current class, any of the exceptions pertaining to the nestmate test (5.4.4) may be thrown.

Run-time Exception

Otherwise, if execution of this aconst_init instruction causes initialization of the referenced class, aconst_init may throw an Error as detailed in 5.5.

Notes

The aconst_init instruction is similar to the new instruction. But unlike new, the aconst_init instruction does not necessarily allocate a new object on the garbage-collected heap; instead, a previously-created class instance can be used. Also unlike new, the class instance provided by aconst_init is completely initialized—there is no need to invoke an instance initialization method.

The aconst_init instruction may not be used on value classes declared outside of the current class's nest. Those classes may declare value class instance creation methods (2.9.4) or other mechanisms to provide classes outside of the nest with a controlled path for instance creation.

The withfield instruction is used to create value class instances other than the initial instance.

if_acmp<cond>

Operation

Branch if reference comparison succeeds

Format

if_acmp<cond>
branchbyte1
branchbyte2

Forms

if_acmpeq = 165 (0xa5)

if_acmpne = 166 (0xa6)

Operand Stack

..., value1, value2

...

Description

Both value1 and value2 must be of type reference. They are both popped from the operand stack and compared. The results of the comparison are as follows:

  • if_acmpeq succeeds if and only if value1 = value2 value1 and value2 are the same

  • if_acmpne succeeds if and only if value1 value2 value1 and value2 are not the same

Two references are the same if one of the following cases applies:

  • Both references are null.

  • Both references are to identity objects with the same identity (2.4).

  • Both references are to value objects that are instances of the same value class, with instance fields whose values are all the same. Field values are compared according to the following rules:

    • For reference-typed fields, these rules are applied recursively.

    • For fields of type int, boolean, char, byte, or short, the values are the same if a comparison via if_icmpeq would succeed (6.5.if_icmpeq).

    • For fields of type long, the values are the same if a comparison via lcmp would produce 0 (6.5.lcmp).

    • For fields of type float, the values are the same if, after applying the conversion defined by the method Float.floatToIntBits, a comparison via if_icmpeq would succeed.

    • For fields of type double, the values are the same if, after applying the conversion defined by the method Double.doubleToLongBits, a comparison via lcmp would produce 0.

If the comparison succeeds, the unsigned branchbyte1 and branchbyte2 are used to construct a signed 16-bit offset, where the offset is calculated to be (branchbyte1 << 8) | branchbyte2. Execution then proceeds at that offset from the address of the opcode of this if_acmp<cond> instruction. The target address must be that of an opcode of an instruction within the method that contains this if_acmp<cond> instruction.

Otherwise, if the comparison fails, execution proceeds at the address of the instruction following this if_acmp<cond> instruction.

This new behavior carries some (deliberately accepted) performance and security risks. Recursion on a standard reference type leading to another value object may occur to an arbitrary depth (although it must eventually terminate—circular value objects are impossible to create). And an attacker with the ability to create arbitrary value class instances can use if_acmpeq to infer the contents of a private field.

monitorenter

Operation

Enter monitor for object

Format

monitorenter

Forms

monitorenter = 194 (0xc2)

Operand Stack

..., objectref

...

Description

The objectref must be of type reference.

Each identity object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:

  • If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.

  • If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.

  • If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.

Run-time Exception

If objectref is null, monitorenter throws a NullPointerException.

Otherwise, if objectref is a value object, monitorenter throws an IllegalMonitorStateException.

Notes

A monitorenter instruction may be used with one or more monitorexit instructions (6.5.monitorexit) to implement a synchronized statement in the Java programming language (3.14). The monitorenter and monitorexit instructions are not used in the implementation of synchronized methods, although they can be used to provide equivalent locking semantics. Monitor entry on invocation of a synchronized method, and monitor exit on its return, are handled implicitly by the Java Virtual Machine's method invocation and return instructions, as if monitorenter and monitorexit were used.

The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object.

The synchronization constructs of the Java programming language require support for operations on monitors besides entry and exit. These include waiting on a monitor (Object.wait) and notifying other threads waiting on a monitor (Object.notifyAll and Object.notify). These operations are supported in the standard package java.lang supplied with the Java Virtual Machine. No explicit support for these operations appears in the instruction set of the Java Virtual Machine.

monitorexit

Operation

Exit monitor for object

Format

monitorexit

Forms

monitorexit = 195 (0xc3)

Operand Stack

..., objectref

...

Description

The objectref must be of type reference.

The thread that executes monitorexit must be the owner of the monitor associated with the instance identity object referenced by objectref.

The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

Run-time Exceptions

If objectref is null, monitorexit throws a NullPointerException.

Otherwise, if objectref is a value object, monitorexit throws an IllegalMonitorStateException.

Otherwise, if the thread that executes monitorexit is not the owner of the monitor associated with the instance identity object referenced by objectref, monitorexit throws an IllegalMonitorStateException.

Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the second of those rules is violated by the execution of this monitorexit instruction, then monitorexit throws an IllegalMonitorStateException.

Notes

One or more monitorexit instructions may be used with a monitorenter instruction (6.5.monitorenter) to implement a synchronized statement in the Java programming language (3.14). The monitorenter and monitorexit instructions are not used in the implementation of synchronized methods, although they can be used to provide equivalent locking semantics.

The Java Virtual Machine supports exceptions thrown within synchronized methods and synchronized statements differently:

  • Monitor exit on normal synchronized method completion is handled by the Java Virtual Machine's return instructions. Monitor exit on abrupt synchronized method completion is handled implicitly by the Java Virtual Machine's athrow instruction.

  • When an exception is thrown from within a synchronized statement, exit from the monitor entered prior to the execution of the synchronized statement is achieved using the Java Virtual Machine's exception handling mechanism (3.14).

new

Operation

Create new identity object

Format

new
indexbyte1
indexbyte2

Forms

new = 187 (0xbb)

Operand Stack

...

..., objectref

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class or interface. The named class or interface is resolved (5.4.3.1) and should result in a non-abstract identity class or the class Object. The named class is initialized if it has not already been initialized (5.5).

Memory for a new instance of that class is allocated from the garbage-collected heap, and the instance variables of the new object are initialized to the default initial values of their types (2.3, 2.4). The objectref, a reference to the instance, is pushed onto the operand stack.

On successful resolution of the class, it is initialized if it has not already been initialized (5.5).

Linking Exceptions

During resolution of the symbolic reference to the class or interface, any of the exceptions documented in 5.4.3.1 can be thrown.

Otherwise, if the symbolic reference to the class or interface type resolves to an interface, or an abstract class, or a value class, new throws an InstantiationError.

Run-time Exception

Otherwise, if execution of this new instruction causes initialization of the referenced class, new may throw an Error as detailed in 5.5.

Notes

The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method (2.9.1) has been invoked on the uninitialized instance.

withfield

Design discussion: use of the withfield instruction is restricted to nestmates of the field's declaring class. This prevents unauthorized creation of value class instances, including for classes that declare public fields.

Alternatively, we could provide a mechanism to express more permissive withfield access for those classes that do not care to control instance creation through value class instance creation methods or other validation logic. This would require new accessibility attributes on fields or classes, independent of the "read" access described by ACC_PUBLIC, etc.

Operation

Duplicate value object with new field value

Format

withfield
indexbyte1
indexbyte2

Forms

withfield = 204 (0xcc)

Operand Stack

..., objectref1, value

..., objectref2

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a field (5.1), which gives the name and descriptor of the field as well as a symbolic reference to the type in which the field is to be found. The referenced field is resolved (5.4.3.2).

The objectref1 must be an instance of a value class, and the resolved field must be declared by that class.

The type of a value stored by a withfield instruction must be compatible with the descriptor of the referenced field (4.3.2). If the field descriptor type is boolean, byte, char, short, or int, then the value must be an int. If the field descriptor type is float, long, or double, then the value must be a float, long, or double, respectively. If the field descriptor type is a reference type, then the value must be of a type that is assignment compatible (JLS §5.2) with the field descriptor type.

The resolved field must be declared by a class that belongs to the same nest as the current class, according to the nestmate test in 5.4.4.

The value and objectref1 are popped from the operand stack.

If the value is of type int and the field descriptor type is boolean, then the int value is narrowed by taking the bitwise AND of value and 1, resulting in value'. Otherwise, the value undergoes value set conversion (2.8.3), resulting in value'.

A reference to an instance of the value class, objectref2, is pushed onto the operand stack. The referenced field in objectref2 is set to value'. Every other instance field in objectref2 is set to the corresponding field's value in objectref1. Memory for objectref2 may be newly allocated from the garbage-collected heap, or may have been allocated previously.

Linking Exceptions

During resolution of the symbolic reference to the field, any of the exceptions pertaining to field resolution (5.4.3.2) can be thrown.

Otherwise, if the resolved field is a static field, or the resolved field is not declared by a non-abstract value class, withfield throws an IncompatibleClassChangeError.

Otherwise, if the resolved field is not declared by a class that belongs to the same nest as the current class, any of the exceptions pertaining to the nestmate test (5.4.4) may be thrown.

Run-time Exception

Otherwise, if objectref1 is null, the withfield instruction throws a NullPointerException.

Notes

The withfield instruction may not be used on value classes declared outside of the current class's nest. Those classes may declare value class instance creation methods (2.9.4) or other mechanisms to provide classes outside of the nest with a controlled path for instance creation.