Value Classes and Objects

Changes to the Java® Virtual Machine Specification • Version 23-internal-adhoc.dlsmith.20240624

This document describes changes to the Java Virtual Machine Specification, Java SE 22 Edition to support value classes and objects, a preview feature introduced by JEP 401.

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 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. Two value objects, however created, are considered the same if they are instances of the same class and their instance fields have the same values. These objects have immutable instance fields and cannot be used for synchronization. A Java Virtual Machine implementation can sometimes optimize the encoding of 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.

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 has the 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
17 September 2021 61 45 .. 61
18 March 2022 62 45 .. 62
19 September 2022 63 45 .. 63
20 March 2023 64 45 .. 64
21 September 2023 65 45 .. 65
22 March 2024 66 45 .. 66

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 Java Virtual Machine implementation which conforms to Java SE N (N 12) must behave as follows:

  • A class file that depends on the preview features of Java SE N may be loaded only when the preview features of Java SE N are enabled.

  • A class file that depends on the preview features of another Java SE release must never be loaded.

  • A class file that does not depend on the preview features of any Java SE release may be loaded 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_SUPER ACC_IDENTITY 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction. Is an identity class, not a value class or an 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 interface.
ACC_ENUM 0x4000 Declared as an enum class.
ACC_MODULE 0x8000 Is a module, not a class or interface.

The ACC_MODULE flag indicates that this class file defines a module, not a class or interface. If the ACC_MODULE flag is set, then special rules apply to the class file which are given at the end of this section. If the ACC_MODULE flag is not set, then the rules immediately below the current paragraph apply to the class file.

An interface is distinguished by the ACC_INTERFACE flag being set. If the ACC_INTERFACE flag is not set, this class file defines a class, not an interface or module.

If the ACC_INTERFACE flag is set, the ACC_ABSTRACT flag must also be set, and the ACC_FINAL, ACC_SUPER ACC_IDENTITY, ACC_ENUM, and ACC_MODULE flags set must not be set.

If the ACC_INTERFACE flag is not set, any of the other flags in Table 4.1-B may be set except ACC_ANNOTATION and ACC_MODULE. However, such a class file must have at least one of its ACC_FINAL, ACC_IDENTITY, or ACC_ABSTRACT flags set, and must not have both its ACC_FINAL and ACC_ABSTRACT flags set (JLS §8.1.1.2).

The ACC_SUPER flag indicates which of two alternative semantics is to be expressed by the invokespecial instruction (6.5.invokespecial) if it appears in this class or interface. Compilers to the instruction set of the Java Virtual Machine should set the ACC_SUPER flag. In Java SE 8 and above, the Java Virtual Machine considers the ACC_SUPER flag to be set in every class file, regardless of the actual value of the flag in the class file and the version of the class file.

The ACC_SUPER flag exists for backward compatibility with code compiled by older compilers for the Java programming language. Prior to JDK 1.0.2, the compiler generated access_flags in which the flag now representing ACC_SUPER had no assigned meaning, and Oracle's Java Virtual Machine implementation ignored the flag if it was set.

In a class file with version number 67.65535, the ACC_IDENTITY flag indicates that the class is an identity class (2.4). If the ACC_IDENTITY flag of a class is not set, the class is a value class.

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 the class is an identity class.

Instances of an identity class are identity objects, and instances of a value class are value objects. Class loading ensures that, with the exception of the special class Object, if an identity class has a subclass, that subclass is also an identity class (5.3.5).

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.

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

An annotation interface (JLS §9.6) must have its ACC_ANNOTATION flag set. 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 should be ignored by Java Virtual Machine implementations.

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) representing the class or interface defined by this class file.

super_class

For a class, the value of the super_class item either must be zero or must be a valid index into the constant_pool table. If the value of the super_class item is nonzero, the constant_pool entry at that index must be a CONSTANT_Class_info structure representing the direct superclass of the class defined by this class file. Neither the direct superclass nor any of its superclasses may have the ACC_FINAL flag set in the access_flags item of its ClassFile structure.

If the value of the super_class item is zero, then this class file must represent the class Object, the only class or interface without a direct superclass.

For an interface, the value of the super_class item must always be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the class Object.

interfaces_count

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

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 representing an interface that is a direct superinterface of this class or interface type, in the left-to-right order given in the source for the type.

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 type.

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.

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. If neither of the ACC_NATIVE and ACC_ABSTRACT flags are set in the access_flags item of a method_info structure, the Java Virtual Machine instructions implementing the method are also supplied.

The method_info structures represent all methods declared by this class or interface type, 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 non-predefined attributes in the attributes table of a ClassFile structure are given in 4.7.1.

If the ACC_MODULE flag is set in the access_flags item, then no other flag in the access_flags item may be set, and the following rules apply to the rest of the ClassFile structure:

4.5 Fields

Each field is described by a field_info structure.

No two fields in one class file may have 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_STRICT 0x0800 A strictly-initialized final field; may not be assigned after another constructor is invoked.
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 may 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 a class file with version number 67.65535, a field that has set ACC_STRICT must not have set ACC_STATIC, and must have set ACC_FINAL.

In a class file with any other version number, the 0x0800 bit is ignored, and the ACC_STRICT flag is considered not to be set.

Each field of a value class must have exactly one of its ACC_STATIC or ACC_STRICT 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 should be 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 denoting a field (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).

A field can have any number of optional attributes associated with it.

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 non-predefined 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.

No two methods in one class file may have 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 In a class file whose major version number is at least 46 and at most 60: Declared strictfp.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.

The value 0x0800 is interpreted as the ACC_STRICT flag only in a class file whose major version number is at least 46 and at most 60. For methods in such a class file, the rules below determine whether the ACC_STRICT flag may be set in combination with other flags. (Setting the ACC_STRICT flag constrained a method's floating-point instructions in Java SE 1.2 through 16 (2.8).) For methods in a class file whose major version number is less than 46 or greater than 60, the value 0x0800 is not interpreted as the ACC_STRICT flag, but rather is unassigned; it is not meaningful to "set the ACC_STRICT flag" in such a class file.

Methods of classes may have any of the flags in Table 4.6-A set. However, each method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS §8.4.3).

Each method of a value class that has its ACC_SYNCHRONIZED flag set must also have its ACC_STATIC flag set.

Methods of interfaces may have any of the flags in Table 4.6-A set except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS §9.4). In a class file whose version number is less than 52.0, each method of an interface must have its ACC_PUBLIC and ACC_ABSTRACT flags set; in a class file whose version number is 52.0 or above, each method of an interface must have exactly one of its ACC_PUBLIC and ACC_PRIVATE 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, or ACC_NATIVE flags set, nor (in a class file whose major version number is at least 46 and at most 60) have its ACC_STRICT flag set.

An instance initialization method (2.9.1) may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set, and may also have its ACC_VARARGS and ACC_SYNTHETIC flags set, and may also (in a class file whose major version number is at least 46 and at most 60) have its ACC_STRICT flag set, but must not have any of the other flags in Table 4.6-A set.

In a class file whose version number is 51.0 or above, a method whose name is <clinit> must have its ACC_STATIC flag set.

A class or interface initialization method (2.9.2) is called implicitly by the Java Virtual Machine. The value of its access_flags item is ignored except for the setting of the ACC_STATIC flag and (in a class file whose major version number is at least 46 and at most 60) the ACC_STRICT flag, and the method is exempt from the preceding rules about legal combinations of flags.

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. A method declared to take a variable number of arguments must be compiled with the ACC_VARARGS flag set to 1. All other methods must be compiled with the ACC_VARARGS flag set to 0.

The ACC_SYNTHETIC flag indicates that this method was generated by a compiler and does not appear in source code, unless it is 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. (This includes the bit corresponding to 0x0800 in a class file whose major version number is less than 46 or greater than 60.) They should be set to zero in generated class files and should be 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 either a valid unqualified name denoting a method (4.2.2), or (if this method is in a class rather than an interface) the special method name <init>, or the special method name <clinit>.

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 this method is in a class rather than an interface, and 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, and, in a class file whose version number is 51.0 or above, a method that takes no arguments.

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.

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).

A method can have any number of optional attributes associated with it.

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 non-predefined 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) representing 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.

30 31 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 class file structures 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 three groups according to their purpose:

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

    • ConstantValue
    • Code
    • StackMapTable
    • BootstrapMethods
    • NestHost
    • NestMembers
    • PermittedSubclasses
    • LoadableDescriptors

    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. Ten attributes are not critical to correct interpretation of the class file by the Java Virtual Machine, but are either critical to correct interpretation of the class file by the class libraries of the Java SE Platform, or are useful for tools (in which case the section that specifies an attribute describes it as "optional"):

    • Exceptions
    • InnerClasses
    • EnclosingMethod
    • Synthetic
    • Signature
    • Record
    • SourceFile
    • LineNumberTable
    • LocalVariableTable
    • LocalVariableTypeTable

    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.

  3. Thirteen 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"):

    • SourceDebugExtension
    • Deprecated
    • RuntimeVisibleAnnotations
    • RuntimeInvisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • RuntimeInvisibleTypeAnnotations
    • AnnotationDefault
    • MethodParameters
    • Module
    • ModulePackages
    • ModuleMainClass

    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
PermittedSubclasses 4.7.31 61.0 17
LoadableDescriptors 4.7.32 67.65535 23

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
PermittedSubclasses 61.0 17 4.7.31
LoadableDescriptors 67.65535 23 4.7.32

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
PermittedSubclasses ClassFile 61.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
LoadableDescriptors ClassFile 67.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

The InnerClasses attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1).

If the constant pool of a class or interface C contains at least one CONSTANT_Class_info entry (4.4.1) which represents a class or interface that is not a member of a package, then there must be exactly one InnerClasses attribute in the attributes table of the ClassFile structure for C.

The InnerClasses attribute has the following format:

InnerClasses_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_classes;
    {   u2 inner_class_info_index;
        u2 outer_class_info_index;
        u2 inner_name_index;
        u2 inner_class_access_flags;
    } classes[number_of_classes];
}

The items of the InnerClasses_attribute structure are as follows:

attribute_name_index

The value of the attribute_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 the string "InnerClasses".

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[]

Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is not a package member must have exactly one corresponding entry in the classes array.

If a class or interface has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member (JLS §13.1), even if that member is not otherwise mentioned by the class.

In addition, the constant_pool table of every nested class and nested interface must refer to its enclosing class, so altogether, every nested class and nested interface will have InnerClasses information for each enclosing class and for each of its own nested classes and interfaces.

Each entry in the classes array contains the following four items:

inner_class_info_index

The value of the inner_class_info_index 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 representing C.

outer_class_info_index

If C is not a member of a class or an interface - that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5) - then the value of the outer_class_info_index item must be zero.

Otherwise, the value of the outer_class_info_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Class_info structure representing the class or interface of which C is a member. The value of the outer_class_info_index item must not equal the the value of the inner_class_info_index item.

inner_name_index

If C is anonymous (JLS §15.9.5), the value of the inner_name_index item must be zero.

Otherwise, the value of the inner_name_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Utf8_info structure that represents the original simple name of C, as given in the source code from which this class file was compiled.

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 A class not marked value in source.
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.

If a class file has a version number that is 51.0 or above, and has an InnerClasses attribute in its attributes table, then for all entries in the classes array of the InnerClasses attribute, the value of the outer_class_info_index item must be zero if the value of the inner_name_index item is zero.

Oracle's Java Virtual Machine implementation does not check the consistency of an InnerClasses attribute against a class file representing a class or interface referenced by the attribute.

4.7.32 The LoadableDescriptors Attribute

The LoadableDescriptors attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1) in a version 67.65535 class file. The LoadableDescriptors attribute indicates to a Java Virtual Machine implementation that certain types have properties that may be of interest before their mentioned classes and interfaces would normally be loaded. Classes and interfaces mentioned by LoadableDescriptors may optionally be loaded when the referencing class is derived and created (5.3.5), or during early stages of linking (5.4).

For example, a class with a field whose type is a value class type may include the field's descriptor in its LoadableDescriptors attribute. This would allow the Java Virtual Machine to load that value class and determine an appropriate amount of space for field storage when the class with the field is created.

There may be at most one LoadableDescriptors attribute in the attributes table of a ClassFile structure.

The LoadableDescriptors attribute has the following format:

LoadableDescriptors_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_descriptors;
    u2 descriptors[number_of_descriptors];
}

The items of the LoadableDescriptors_attribute structure are as follows:

attribute_name_index

The value of the attribute_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 the string "LoadableDescriptors".

attribute_length

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

number_of_descriptors

The value of the number_of_descriptors item indicates the number of entries in the descriptors array.

descriptors[]

Each entry in the descriptors array 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 field descriptor (4.3.2).

4.9 Constraints on Java Virtual Machine Code

4.9.2 Structural Constraints

The structural constraints on the code array specify constraints on relationships between Java Virtual Machine instructions. The structural constraints are as follows:

4.10 Verification of class Files

4.10.1 Verification by Type Checking

4.10.1.1 Accessors for Java Virtual Machine Artifacts

We stipulate the existence of 27 28 Prolog predicates ("accessors") that have certain expected behavior but whose formal definitions are not given in this specification.

classClassName(Class, ClassName)

Extracts the name, ClassName, of the class Class.

classIsInterface(Class)

True iff the class, Class, is an interface.

classIsNotFinal(Class)

True iff the class, Class, is not a final class.

classSuperClassName(Class, SuperClassName)

Extracts the name, SuperClassName, of the superclass of class Class.

classInterfaces(Class, Interfaces)

Extracts a list, Interfaces, of the direct superinterfaces of the class Class.

classMethods(Class, Methods)

Extracts a list, Methods, of the methods declared in the class Class.

classAttributes(Class, Attributes)

Extracts a list, Attributes, of the attributes of the class Class.

Each attribute is represented as a functor application of the form attribute(AttributeName, AttributeContents), where AttributeName is the name of the attribute. The format of the attribute's contents is unspecified.

classDeclaresMember(Class, MemberName, MemberDescriptor)

Asserts that a class, Class, declares a field or method with name MemberName and descriptor MemberDescriptor. This assertion does not consider members declared in the superclasses or superinterfaces of Class.

classDeclaresStrictField(Class, FieldName, FieldDescriptor)

Asserts that a class, Class, declares a field with name FieldName and descriptor FieldDescriptor, and that field has its ACC_STRICT flag set.

classDefiningLoader(Class, Loader)

Extracts the defining class loader, Loader, of the class Class.

isBootstrapLoader(Loader)

True iff the class loader Loader is the bootstrap class loader.

loadedClass(Name, InitiatingLoader, ClassDefinition)

True iff there exists a class named Name whose representation (in accordance with this specification) when loaded by the class loader InitiatingLoader is ClassDefinition.

methodName(Method, Name)

Extracts the name, Name, of the method Method.

methodAccessFlags(Method, AccessFlags)

Extracts the access flags, AccessFlags, of the method Method.

methodDescriptor(Method, Descriptor)

Extracts the descriptor, Descriptor, of the method Method.

methodAttributes(Method, Attributes)

Extracts a list, Attributes, of the attributes of the method Method.

Each attribute is represented as a functor application of the form attribute(AttributeName, AttributeContents), where AttributeName is the name of the attribute. The format of the attribute's contents is unspecified.

isInit(Method)

True iff Method (regardless of class) is <init>.

isNotInit(Method)

True iff Method (regardless of class) is not <init>.

isNotFinal(Method, Class)

True iff Method in class Class is not final.

isStatic(Method, Class)

True iff Method in class Class is static.

isNotStatic(Method, Class)

True iff Method in class Class is not static.

isPrivate(Method, Class)

True iff Method in class Class is private.

isNotPrivate(Method, Class)

True iff Method in class Class is not private.

isProtected(MemberClass, MemberName, MemberDescriptor)

True iff there is a member named MemberName with descriptor MemberDescriptor in the class MemberClass and it is protected.

isNotProtected(MemberClass, MemberName, MemberDescriptor)

True iff there is a member named MemberName with descriptor MemberDescriptor in the class MemberClass and it is not protected.

parseFieldDescriptor(Descriptor, Type)

Converts a field descriptor, Descriptor, into the corresponding verification type Type (4.10.1.2).

parseMethodDescriptor(Descriptor, ArgTypeList, ReturnType)

Converts a method descriptor, Descriptor, into a list of verification types, ArgTypeList, corresponding to the method argument types, and a verification type, ReturnType, corresponding to the return type.

parseCodeAttribute(Class, Method, FrameSize, MaxStack, ParsedCode, Handlers, StackMap)

Extracts the instruction stream, ParsedCode, of the method Method in Class, as well as the maximum operand stack size, MaxStack, the maximal number of local variables, FrameSize, the exception handlers, Handlers, and the stack map StackMap.

The representation of the instruction stream and stack map attribute must be as specified in 4.10.1.3 and 4.10.1.4.

samePackageName(Class1, Class2)

True iff the package names of Class1 and Class2 are the same.

differentPackageName(Class1, Class2)

True iff the package names of Class1 and Class2 are different.

When type checking a method's body, it is convenient to access information about the method. For this purpose, we define an environment, a six-tuple consisting of:

We specify accessors to extract information from the environment.

allInstructions(Environment, Instructions) :-
    Environment = environment(_Class, _Method, _ReturnType,
                              Instructions, _, _).

exceptionHandlers(Environment, Handlers) :-
    Environment = environment(_Class, _Method, _ReturnType,
                              _Instructions, _, Handlers).

maxOperandStackLength(Environment, MaxStack) :-
    Environment = environment(_Class, _Method, _ReturnType,
                              _Instructions, MaxStack, _Handlers).

thisClass(Environment, class(ClassName, L)) :-
    Environment = environment(Class, _Method, _ReturnType,
                              _Instructions, _, _),
    classDefiningLoader(Class, L),
    classClassName(Class, ClassName).

thisMethodReturnType(Environment, ReturnType) :-
    Environment = environment(_Class, _Method, ReturnType,
                              _Instructions, _, _).

We specify additional predicates to extract higher-level information from the environment.

offsetStackFrame(Environment, Offset, StackFrame) :-
    allInstructions(Environment, Instructions),
    member(stackMap(Offset, StackFrame), Instructions).

currentClassLoader(Environment, Loader) :-
    thisClass(Environment, class(_, Loader)).

Finally, we specify a general predicate used throughout the type rules:

notMember(_, []).
notMember(X, [A | More]) :- X \= A, notMember(X, More).

The principle guiding the determination as to which accessors are stipulated and which are fully specified is that we do not want to over-specify the representation of the class file. Providing specific accessors to the Class or Method term would force us to completely specify the format for a Prolog term representing the class file.

4.10.1.9 Type Checking Instructions
putfield

A putfield instruction with operand CP is type safe iff all of the following are true:

instructionIsTypeSafe(putfield(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :- 
    \+ currentClassStrictField(Environment, CP),
    CP = field(FieldClassName, FieldName, FieldDescriptor),
    parseFieldDescriptor(FieldDescriptor, FieldType),   
    canPop(StackFrame, [FieldType], PoppedFrame),
    passesProtectedCheck(Environment, FieldClassName, FieldName,
                         FieldDescriptor, PoppedFrame),
    currentClassLoader(Environment, CurrentLoader),
    canPop(StackFrame, [FieldType, class(FieldClassName, CurrentLoader)],
           NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
currentClassStrictField(Environment, CP) :-
    CP = field(FieldClassName, FieldName, FieldDescriptor),
    thisClass(Environment, CurrentClass),
    classClassName(CurrentClass, FieldClassName),
    classDeclaresStrictField(CurrentClass, FieldName, FieldDescriptor).

The \+ operator is commonly used in Prolog to indicate negation. The new clause prevents this rule from applying when the given field is declared ACC_STRICT in the current class. (And note that any attempts to write to an ACC_STRICT field declared in another class will fail with a linkage error, due to the field being ACC_FINAL.)

instructionIsTypeSafe(putfield(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    CP = field(FieldClassName, FieldName, FieldDescriptor),
    parseFieldDescriptor(FieldDescriptor, FieldType),
    Environment = environment(CurrentClass, CurrentMethod, _, _, _, _),
    CurrentClass = class(FieldClassName, _),
    isInit(CurrentMethod),
    classDeclaresMember(CurrentClass, FieldName, FieldDescriptor),
    canPop(StackFrame, [FieldType, uninitializedThis], 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 baseline text in this section includes the bug fix described in JDK-8268628.

Class loaders require the cooperation of the Java Virtual Machine to derive and create a class or interface from a binary representation provided by the loader (5.3.1, 5.3.2).

These requests to derive a class or interface may come from multiple threads, but the derivation process is sequential. The Java Virtual Machine implementation ensures that only one attempt to derive a class or interface of a particular name using a particular loader is processed at a time, while all other attempts wait until the first attempt is complete.

If the first attempt is successful, all subsequent attempts will be considered invalid. The ClassLoader API provides mechanisms to synchronize derivation attempts and cache successful results so that redundant derivation attempts do not occur.

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

  1. First, the Java Virtual Machine determines whether the attempt to derive a class or interface denoted by N using class loader L is valid.

    If L has already been recorded as an initiating loader of a class or interface denoted by N, derivation throws a LinkageError.

    If the Java Virtual Machine is already in the process of deriving a class or interface denoted by N using class loader L, derivation throws a ClassCircularityError.

    We may find it useful to distinguish here between a true ClassCircularityError and a recursive dependency encountered during a speculative load in step 5—call it a SpeculativeClassLoadingError. For now, we'll stick with using ClassCircularityError in both cases.

  2. Next, the Java Virtual Machine attempts to parse the purported representation. The purported representation may not in fact be a valid representation of C, so derivation must detect the following problems:

    • If the purported representation is not a ClassFile structure (4.1, 4.8), derivation throws a ClassFormatError.

    • Otherwise, if the purported representation is not of a supported major or minor version (4.1), derivation throws an UnsupportedClassVersionError.

      UnsupportedClassVersionError, a subclass of ClassFormatError, was introduced in JDK 1.2 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 does not actually represent a class or interface named N, derivation throws a NoClassDefFoundError.

      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, with L acting as the defining loader of C. Note that if C is an interface it must have Object as its direct superclass, which must already have been loaded. Only Object has no direct superclass.

    Any exception that can be thrown as a result of failure of class or interface resolution can be thrown as a result of derivation. In addition, derivation must detect the following problems:

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

    • Otherwise, if C is a value class and the class named as the direct superclass of C is neither the class Object nor a value class, loading throws an IncompatibleClassChangeError.

    • Otherwise, if the class named as the direct superclass of C has a PermittedSubclasses attribute (4.7.31) and any of the following is true, derivation throws an IncompatibleClassChangeError:

      • The superclass is in a different run-time module than C (5.3.6).

      • C does not have its ACC_PUBLIC flag set (4.1) and the superclass is in a different run-time package than C (5.3).

      • No entry in the classes array of the superclass's PermittedSubclasses attribute refers to a class or interface with the name N.

    • 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, derivation 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, with L acting as the defining loader of C.

    Any exception that can be thrown as a result of failure of class or interface resolution can be thrown as a result of derivation. In addition, derivation must detect the following problems:

    • If any class or interface named as a direct superinterface of C is not in fact an interface, derivation throws an IncompatibleClassChangeError.

    • Otherwise, for each direct superinterface named by C, if the superinterface has a PermittedSubclasses attribute (4.7.31) and any of the following is true, derivation throws an IncompatibleClassChangeError:

      • The superinterface is in a different run-time module than C.

      • C does not have its ACC_PUBLIC flag set (4.1) and the superinterface is in a different run-time package than C.

      • No entry in the classes array of the superinterface's PermittedSubclasses attribute refers to a class or interface with the name N.

  1. If C has a LoadableDescriptors attribute (4.7.32), a Java Virtual Machine implementation may optionally use L to speculatively load any of the classes or interfaces mentioned by the entries of the descriptors array of the LoadableDescriptors attribute.

    When speculatively loading a class or interface, any exception that is thrown as a result of failure to load the class or interface is ignored and discarded. This step of derivation always completes successfully.

    For example, two classes, A and B, may mention each other in their LoadableDescriptors attributes. An attempt to derive A may cause a Java Virtual Machine implementation to speculatively load B. In turn, the attempt to derive B may cause the Java Virtual Machine implementation to speculatively load A. At this point, the implementation is already in the process of deriving A, so in Step 1 the recursive attempt will fail with a ClassCircularityError. In Step 5 of the attempt to derive B, the error will be discarded and the process will continue, ultimately completing successfully. Then the original attempt to derive A will receive the loaded class B from the class loader, use B to help with the derivation of A, and successfully complete the creation process for A. Subsequent attempts to load A outside of class derivation will see that A has been successfully loaded, and will not observe the ClassCircularityError.

If no exception is thrown in steps 1-4, then derivation of the class or interface C succeeds. The Java Virtual Machine marks C to have L as its defining loader, records that L is an initiating loader of C (5.3.4), and creates C in the method area (2.5.4).

When derivation succeeds, the process of loading and creating C is not complete until every class loader that was involved in loading C (directly or indirectly) returns C as its result. Depending on the behavior of user-defined class loaders, the process of loading and creating C may yet fail (5.3.2).

If an exception is thrown in steps 1-4, then derivation of the class or interface C fails with that exception.

5.4 Linking

Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary. Linking also involves resolution of symbolic references in the class or interface, though not necessarily at the same time as the class or interface is verified and prepared.

This specification allows an implementation flexibility as to when linking activities (and, because of recursion, loading) take place, provided that all of the following properties are maintained:

For example, a Java Virtual Machine implementation may choose a "lazy" linkage strategy, where each symbolic reference in a class or interface (other than the symbolic references above) is resolved individually when it is used. Alternatively, an implementation may choose an "eager" linkage strategy, where all symbolic references are resolved at once when the class or interface is being verified. This means that the resolution process may continue, in some implementations, after a class or interface has been initialized. Whichever strategy is followed, any error detected during resolution must be thrown at a point in the program that (directly or indirectly) uses a the symbolic reference to the class or interface whose resolution caused the error.

If a class being linked has a LoadableDescriptors attribute (4.7.32), then during any phase of linking, a Java Virtual Machine implementation may optionally load any of the classes or interfaces mentioned by the entries of the descriptors array of the LoadableDescriptors attribute. Any exception that is thrown as a result of failure to load the class or interface must be ignored and discarded.

Because linking involves the allocation of new data structures, it may fail with an OutOfMemoryError.

Chapter 6: The Java Virtual Machine Instruction Set

6.5 Instructions

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_icmp_cond).

    • 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.floatToRawIntBits, 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.doubleToRawLongBits, 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 reference type may lead to another value object comparison, and this may repeat to an arbitrary depth (although it must eventually terminate—circular value objects are impossible to create without an intermediate identity object). And an attacker with the ability to create arbitrary value class instances can use if_acmpeq to infer the contents of a private field.

invokespecial

Operation

Invoke instance method; direct invocation of instance initialization methods and methods of the current class and its supertypes

Format

invokespecial
indexbyte1
indexbyte2

Forms

invokespecial = 183 (0xb7)

Operand Stack

..., objectref, [arg1, [arg2 ...]]

...

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 method or an interface method (5.1), which gives the name and descriptor (4.3.3) of the method or interface method as well as a symbolic reference to the class or interface in which the method or interface method is to be found. The named method is resolved (5.4.3.3, 5.4.3.4).

If all of the following are true, let C be the direct superclass of the current class:

  • The resolved method is not an instance initialization method (2.9.1).

  • The symbolic reference names a class (not an interface), and that class is a superclass of the current class.

  • The ACC_SUPER flag is set for the class file (4.1).

If the symbolic reference names a class (not an interface) that is a superclass of the current class, and the resolved method is not an instance initialization method (2.9.1), let C be the direct superclass of the current class. Otherwise, let C be the class or interface named by the symbolic reference.

The actual method to be invoked is selected by the following lookup procedure:

  1. If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.

  2. Otherwise, if C is a class and has a superclass, a search for a declaration of an instance method with the same name and descriptor as the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a match is found or no further superclasses exist. If a match is found, then it is the method to be invoked.

  3. Otherwise, if C is an interface and the class Object contains a declaration of a public instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.

  4. Otherwise, if there is exactly one maximally-specific method (5.4.3.3) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract, then it is the method to be invoked.

The objectref must be of type reference and must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the selected instance method.

If the method is synchronized, the monitor associated with objectref is entered or reentered as if by execution of a monitorenter instruction (6.5.monitorenter) in the current thread.

If the method is not native, the nargs argument values and objectref are popped from the operand stack. A new frame is created on the Java Virtual Machine stack for the method being invoked. The objectref and the argument values are consecutively made the values of local variables of the new frame, with objectref in local variable 0, arg1 in local variable 1 (or, if arg1 is of type long or double, in local variables 1 and 2), and so on. The new frame is then made current, and the Java Virtual Machine pc is set to the opcode of the first instruction of the method to be invoked. Execution continues with the first instruction of the method.

If the method is native and the platform-dependent code that implements it has not yet been bound (5.6) into the Java Virtual Machine, that is done. The nargs argument values and objectref are popped from the operand stack and are passed as parameters to the code that implements the method. The parameters are passed and the code is invoked in an implementation-dependent manner. When the platform-dependent code returns, the following take place:

  • If the native method is synchronized, the monitor associated with objectref is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread.

  • If the native method returns a value, the return value of the platform-dependent code is converted in an implementation-dependent way to the return type of the native method and pushed onto the operand stack.

Linking Exceptions

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

Otherwise, if the resolved method is an instance initialization method, and the class in which it is declared is not the class symbolically referenced by the instruction, a NoSuchMethodError is thrown.

Otherwise, if the resolved method is a class (static) method, the invokespecial instruction throws an IncompatibleClassChangeError.

Run-time Exceptions

Otherwise, if objectref is null, the invokespecial instruction throws a NullPointerException.

Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects an abstract method, invokespecial throws an AbstractMethodError.

Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects a native method and the code that implements the method cannot be bound, invokespecial throws an UnsatisfiedLinkError.

Otherwise, if step 4 of the lookup procedure determines there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not abstract, invokespecial throws an IncompatibleClassChangeError

Otherwise, if step 4 of the lookup procedure determines there are no maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not abstract, invokespecial throws an AbstractMethodError.

Notes

The difference between the invokespecial instruction and the invokevirtual instruction (6.5.invokevirtual) is that invokevirtual invokes a method based on the class of the object. The invokespecial instruction is used to directly invoke instance initialization methods (2.9.1) as well as methods of the current class and its supertypes.

The invokespecial instruction was named invokenonvirtual prior to JDK release 1.0.2.

The nargs argument values and objectref are not one-to-one with the first nargs+1 local variables. Argument values of types long and double must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.

The invokespecial instruction handles invocation of a non-abstract interface method, referenced either via a direct superinterface or via a superclass. In these cases, the rules for selection are essentially the same as those for invokeinterface (except that the search starts from a different class).

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 IdentityException.

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, or 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).