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:
Repurposing the
ACC_SUPER
flag asACC_IDENTITY
, used to distinguish identity classes from value classes, with associated validation rules (4.1, 4.5, 4.6, 5.3.5)Adding the
ACC_STRICT
flag for final fields, indicating that the field may only be modified in an<init>
method before execution of thesuper()
call (4.5, 4.9.2, 4.10.1.9.putfield)Custom behavior for
if_acmpeq
,if_acmpne
, andmonitorenter
when applied to value objects (6.5.if_acmp_cond, 6.5.monitorenter)Introduction of the
LoadableDescriptors
attribute, which allows JVM implementations, during loading or linking of a class, to eagerly load the classes appearing in certain descriptors (4.7.32, 5.3.5, 5.4)
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:
June 2024: renamed and adjusted encoding of the
LoadableDescriptors
attribute (formerlyPreload
, 4.7.32); no longer throwIdentityException
frommonitorexit
May 2024: clarified that the use of
ACC_STRICT
is version-dependent (4.5);monitorenter
andmonitorexit
may throw anIdentityException
February 2024: allowed speculative loading of
LoadableDescriptors
classes during the class derivation process (5.3.5)January 2024: adopted an
<init>
-based construction scheme paired withACC_STRICT
fields, and combined theACC_IDENTITY
andACC_VALUE
flags into oneMay 2023: revised the
acmp
behavior for floats and doubles (6.5.if_acmp_cond)May 2022: added changes to the
InnerClasses
attribute (4.7.6)April 2022: initial draft
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 named reference type names a class or interface defined in a
class
file. If the type names a class, its values are thenull
reference, references to instances of the named class, and references to instances of the class's subclasses. If the type names an interface, its values are thenull
reference and references to instances of any class that implements the interface. In the special case of the class typeObject
or the interface typesCloneable
orjava.io.Serializable
, the type's values also include all arrays.A named reference type may be called a class type if it names a class, or an interface type if it names an interface.
An array type consists of a component type with a single dimension (whose length is not given by the type). The component type of an array type may
itself be an array typebe any primitive or reference type.If, starting from any array type, one considers its component type, and then (if that is also an array type) the component type of that type, and so on, eventually one must reach a component type that is not an array type; this is called the element type of the array type. The element type of an array type is necessarily either a primitive type, or a class type, or an interface type.If the component type is itself an array type, the array type is multi-dimensional. Every array type has a non-array element type. The element type of a single-dimensional array type is its component type; the element type of a multi-dimensional array type is the element type of its component array type (applying this definition recursively).The values of an array type with component type T are the
null
reference and references to arrays of any length whose component type is T or a subtype of T.
A The default value of 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.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 theclass
file format; it has the value0xCAFEBABE
. - minor_version, major_version
-
The values of the
minor_version
andmajor_version
items are the minor and major version numbers of thisclass
file. Together, a major and a minor version number determine the version of theclass
file format. If aclass
file has major version number M and minor version number m, we denote the version of itsclass
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 aclass
file containing thatmajor_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 versionsJava 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 whosemajor_version
is 56 or above, theminor_version
must be 0 or 65535.For a
class
file whosemajor_version
is between 45 and 55 inclusive, theminor_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 theclass
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 amajor_version
that corresponds to Java SE N (according to Table 4.1-A) and aminor_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 theconstant_pool
table plus one. Aconstant_pool
index is considered valid if it is greater than zero and less thanconstant_pool_count
, with the exception for constants of typelong
anddouble
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 theClassFile
structure and its substructures. The format of eachconstant_pool
table entry is indicated by its first "tag" byte.The
constant_pool
table is indexed from 1 toconstant_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 avalue
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 thisclass
file defines a module, not a class or interface. If theACC_MODULE
flag is set, then special rules apply to theclass
file which are given at the end of this section. If theACC_MODULE
flag is not set, then the rules immediately below the current paragraph apply to theclass
file.An interface is distinguished by the
ACC_INTERFACE
flag being set. If theACC_INTERFACE
flag is not set, thisclass
file defines a class, not an interface or module.If the
ACC_INTERFACE
flag is set, theACC_ABSTRACT
flag must also be set, and theACC_FINAL
,ACC_SUPER
ACC_IDENTITY
,ACC_ENUM
, andACC_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 exceptACC_ANNOTATION
andACC_MODULE
. However, such aclass
file must have at least one of itsACC_FINAL
,ACC_IDENTITY
, orACC_ABSTRACT
flags set, and must not have both itsACC_FINAL
andACC_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 theACC_SUPER
flag. In Java SE 8 and above, the Java Virtual Machine considers theACC_SUPER
flag to be set in everyclass
file, regardless of the actual value of the flag in theclass
file and the version of theclass
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 generatedaccess_flags
in which the flag now representingACC_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, theACC_IDENTITY
flag indicates that the class is an identity class (2.4). If theACC_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 theclass
file defines a class, theACC_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, theACC_SUPER
semantics became mandatory, regardless of the setting ofACC_SUPER
or theclass
file version number, and the flag no longer had any effect. Now the flag has been repurposed asACC_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 theACC_ANNOTATION
flag is set, theACC_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 generatedclass
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure (4.4.1) representing the class or interface defined by thisclass
file. - super_class
-
For a class, the value of the
super_class
item either must be zero or must be a valid index into theconstant_pool
table. If the value of thesuper_class
item is nonzero, theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing the direct superclass of the class defined by thisclass
file. Neither the direct superclass nor any of its superclasses may have theACC_FINAL
flag set in theaccess_flags
item of itsClassFile
structure.If the value of the
super_class
item is zero, then thisclass
file must represent the classObject
, 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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing the classObject
. - 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 theconstant_pool
table. Theconstant_pool
entry at each value ofinterfaces[i]
, where 0 ≤ i <interfaces_count
, must be aCONSTANT_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 offield_info
structures in thefields
table. Thefield_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 afield_info
structure (4.5) giving a complete description of a field in this class or interface. Thefields
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 ofmethod_info
structures in themethods
table. - methods[]
-
Each value in the
methods
table must be amethod_info
structure (4.6) giving a complete description of a method in this class or interface. If neither of theACC_NATIVE
andACC_ABSTRACT
flags are set in theaccess_flags
item of amethod_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). Themethods
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 theattributes
table of this class. - attributes[]
-
Each value of the
attributes
table must be anattribute_info
structure (4.7).The attributes defined by this specification as appearing in the
attributes
table of aClassFile
structure are listed in Table 4.7-C.The rules concerning attributes defined to appear in the
attributes
table of aClassFile
structure are given in 4.7.The rules concerning non-predefined attributes in the
attributes
table of aClassFile
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:
major_version
,minor_version
: ≥ 53.0 (i.e., Java SE 9 and above)this_class
:module-info
super_class
,interfaces_count
,fields_count
,methods_count
: zeroattributes
: OneModule
attribute must be present. Except forModule
,ModulePackages
,ModuleMainClass
,InnerClasses
,SourceFile
,SourceDebugExtension
,RuntimeVisibleAnnotations
, andRuntimeInvisibleAnnotations
, none of the pre-defined attributes (4.7) may appear.
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
, andACC_PROTECTED
flags set (JLS §8.3.1), and must not have both itsACC_FINAL
andACC_VOLATILE
flags set (JLS §8.3.1.4).In a class file with version number
67.65535
, a field that has setACC_STRICT
must not have setACC_STATIC
, and must have setACC_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
orACC_STRICT
flags set.Fields of interfaces must have their
ACC_PUBLIC
,ACC_STATIC
, andACC_FINAL
flags set; they may have theirACC_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 generatedclass
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 anattribute_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 afield_info
structure are listed in Table 4.7-C.The rules concerning attributes defined to appear in the
attributes
table of afield_info
structure are given in 4.7.The rules concerning non-predefined attributes in the
attributes
table of afield_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: Declaredstrictfp
.ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. The value 0x0800 is interpreted as the
ACC_STRICT
flag only in aclass
file whose major version number is at least 46 and at most 60. For methods in such aclass
file, the rules below determine whether theACC_STRICT
flag may be set in combination with other flags. (Setting theACC_STRICT
flag constrained a method's floating-point instructions in Java SE 1.2 through 16 (2.8).) For methods in aclass
file whose major version number is less than 46 or greater than 60, the value 0x0800 is not interpreted as theACC_STRICT
flag, but rather is unassigned; it is not meaningful to "set theACC_STRICT
flag" in such aclass
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
, andACC_PROTECTED
flags set (JLS §8.4.3).Each method of a value class that has its
ACC_SYNCHRONIZED
flag set must also have itsACC_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
, andACC_NATIVE
(JLS §9.4). In aclass
file whose version number is less than 52.0, each method of an interface must have itsACC_PUBLIC
andACC_ABSTRACT
flags set; in aclass
file whose version number is 52.0 or above, each method of an interface must have exactly one of itsACC_PUBLIC
andACC_PRIVATE
flags set.If a method of a class or interface has its
ACC_ABSTRACT
flag set, it must not have any of itsACC_PRIVATE
,ACC_STATIC
,ACC_FINAL
,ACC_SYNCHRONIZED
, orACC_NATIVE
flags set, nor (in aclass
file whose major version number is at least 46 and at most 60) have itsACC_STRICT
flag set.An instance initialization method (2.9.1) may have at most one of its
ACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set, and may also have itsACC_VARARGS
andACC_SYNTHETIC
flags set, and may also (in aclass
file whose major version number is at least 46 and at most 60) have itsACC_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 itsACC_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 theACC_STATIC
flag and (in aclass
file whose major version number is at least 46 and at most 60) theACC_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 theACC_VARARGS
flag set to 1. All other methods must be compiled with theACC_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 aclass
file whose major version number is less than 46 or greater than 60.) They should be set to zero in generatedclass
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 avoid
method.If the name of the method is
<clinit>
, then the descriptor must denote avoid
method, and, in aclass
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 theaccess_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 anattribute_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 amethod_info
structure are listed in Table 4.7-C.The rules concerning attributes defined to appear in the
attributes
table of amethod_info
structure are given in 4.7.The rules concerning non-predefined attributes in the
attributes
table of amethod_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:
Table 4.7-A is ordered by the attributes' section numbers in this chapter. Each attribute is shown with the first version of the
class
file format in which it was defined. Also shown is the version of the Java SE Platform which introduced that version of theclass
file format (4.1).Table 4.7-B is ordered by the first version of the
class
file format in which each attribute was defined.Table 4.7-C is ordered by the location in a
class
file where each attribute is defined to appear.
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:
SevenEight attributes are critical to correct interpretation of theclass
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 theclass
file format, and the attribute was first defined in version v or earlier of theclass
file format, and the attribute appears in a location where it is defined to appear.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 theclass
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 theclass
file format, and the attribute was first defined in version v or earlier of theclass
file format, and the attribute appears in a location where it is defined to appear.Thirteen attributes are not critical to correct interpretation of the
class
file by the Java Virtual Machine, but contain metadata about theclass
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 theclasses
array. - classes[]
-
Every
CONSTANT_Class_info
entry in theconstant_pool
table which represents a class or interface C that is not a package member must have exactly one corresponding entry in theclasses
array.If a class or interface has members that are classes or interfaces, its
constant_pool
table (and hence itsInnerClasses
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 haveInnerClasses
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 theconstant_pool
table, and the entry at that index must be aCONSTANT_Class_info
structure representing the class or interface of which C is a member. The value of theouter_class_info_index
item must not equal the the value of theinner_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 theconstant_pool
table, and the entry at that index must be aCONSTANT_Utf8_info
structure that represents the original simple name of C, as given in the source code from which thisclass
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 thisclass
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 generatedclass
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 anInnerClasses
attribute in itsattributes
table, then for all entries in theclasses
array of theInnerClasses
attribute, the value of theouter_class_info_index
item must be zero if the value of theinner_name_index
item is zero.
Oracle's Java Virtual Machine implementation does not check the consistency of an
InnerClasses
attribute against aclass
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 theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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 thedescriptors
array. - descriptors[]
-
Each entry in the
descriptors
array must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_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:
Each instruction must only be executed with the appropriate type and number of arguments in the operand stack and local variable array, regardless of the execution path that leads to its invocation.
An instruction operating on values of type
int
is also permitted to operate on values of typeboolean
,byte
,char
, andshort
.As noted in 2.3.4 and 2.11.1, the Java Virtual Machine internally converts values of types
boolean
,byte
,short
, andchar
to typeint
.)If an instruction can be executed along several different execution paths, the operand stack must have the same depth (2.6.2) prior to the execution of the instruction, regardless of the path taken.
At no point during execution can the operand stack grow to a depth greater than that implied by the
max_stack
item.At no point during execution can more values be popped from the operand stack than it contains.
At no point during execution can the order of the local variable pair holding a value of type
long
ordouble
be reversed or the pair split up. At no point can the local variables of such a pair be operated on individually.No local variable (or local variable pair, in the case of a value of type
long
ordouble
) can be accessed before it is assigned a value.Each invokespecial instruction must name one of the following:
an instance initialization method (2.9.1)
a method in the current class or interface
a method in a superclass of the current class
a method in a direct superinterface of the current class or interface
a method in
Object
If an invokespecial instruction names an instance initialization method, then the target reference on the operand stack must be an uninitialized class instance. An instance initialization method must never be invoked on an initialized class instance. In addition:
If the target reference on the operand stack is an uninitialized class instance for the current class, then invokespecial must name an instance initialization method from the current class or its direct superclass.
If the target reference on the operand stack is a class instance created by an earlier new instruction, then invokespecial must name an instance initialization method from the class of that class instance.
In either case, if the instruction is covered by an exception handler, then any copy of the target reference stored in a local variable must be treated as unusable by the exception handler code.
If an invokespecial instruction names a method which is not an instance initialization method, then the target reference on the operand stack must be a class instance whose type is assignment compatible with the current class (JLS §5.2).
The general rule for invokespecial is that the class or interface named by invokespecial must be be "above" the caller class or interface, while the receiver object targeted by invokespecial must be "at" or "below" the caller class or interface. The latter clause is especially important: a class or interface can only perform invokespecial on its own objects. See 4.10.1.9.invokespecial for an explanation of how the latter clause is implemented in Prolog.
Each instance initialization method, except for the instance initialization method derived from the constructor of class
Object
, must call either another instance initialization method ofthis
or an instance initialization method of its direct superclasssuper
before its instance members are accessed, and before the calling instance initialization method returns.However, instance fields of
this
that are declared in the current class may be assigned by putfield before calling any instance initialization method.An instance field of
this
declared in the current class with itsACC_STRICT
flag set may only be assigned by a putfield instruction if the assignment occurs before calling an instance initialization method.When any instance method is invoked or when any instance variable is accessed, the class instance that contains the instance method or instance variable must already be initialized.
There must never be an uninitialized class instance on the operand stack or in a local variable when a jsr or jsr_w instruction is executed.
The type of every class instance that is the target of a method invocation instruction (that is, the type of the target reference on the operand stack) must be assignment compatible with the class or interface type specified in the instruction.
The types of the arguments to each method invocation must be method invocation compatible with the method descriptor (JLS §5.3, 4.3.3).
Each return instruction must match its method's return type:
If the method returns a
boolean
,byte
,char
,short
, orint
, only the ireturn instruction may be used.If the method returns a
float
,long
, ordouble
, only an freturn, lreturn, or dreturn instruction, respectively, may be used.If the method returns a
reference
type, only an areturn instruction may be used, and the type of the returned value must be assignment compatible with the return descriptor of the method (4.3.3).All instance initialization methods, class or interface initialization methods, and methods declared to return
void
must use only the return instruction.
The type of every class instance accessed by a getfield instruction or modified by a putfield instruction (that is, the type of the target reference on the operand stack) must be assignment compatible with the class type specified in the instruction.
The type of every value stored by a putfield or putstatic instruction must be compatible with the descriptor of the field (4.3.2) of the class instance or class being stored into:
If the descriptor type is
boolean
,byte
,char
,short
, orint
, then the value must be anint
.If the descriptor type is
float
,long
, ordouble
, then the value must be afloat
,long
, ordouble
, respectively.If the descriptor type is a
reference
type, then the value must be of a type that is assignment compatible with the descriptor type.
The type of every value stored into an array by an aastore instruction must be a
reference
type.The component type of the array being stored into by the aastore instruction must also be a
reference
type.Each athrow instruction must throw only values that are instances of class
Throwable
or of subclasses ofThrowable
.Each class mentioned in a
catch_type
item of theexception_table
array of the method'sCode_attribute
structure must beThrowable
or a subclass ofThrowable
.If getfield or putfield is used to access a
protected
field declared in a superclass that is a member of a different run-time package than the current class, then the type of the class instance being accessed (that is, the type of the target reference on the operand stack) must be assignment compatible with the current class.If invokevirtual or invokespecial is used to access a
protected
method declared in a superclass that is a member of a different run-time package than the current class, then the type of the class instance being accessed (that is, the type of the target reference on the operand stack) must be assignment compatible with the current class.Execution never falls off the bottom of the
code
array.No return address (a value of type
returnAddress
) may be loaded from a local variable.The instruction following each jsr or jsr_w instruction may be returned to only by a single ret instruction.
No jsr or jsr_w instruction that is returned to may be used to recursively call a subroutine if that subroutine is already present in the subroutine call chain. (Subroutines can be nested when using
try
-finally
constructs from within afinally
clause.)Each instance of type
returnAddress
can be returned to at most once.If a ret instruction returns to a point in the subroutine call chain above the ret instruction corresponding to a given instance of type
returnAddress
, then that instance can never be used as a return address.
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 classClass
. - classIsInterface(Class)
-
True iff the class,
Class
, is an interface. - classIsNotFinal(Class)
-
True iff the class,
Class
, is not afinal
class. - classSuperClassName(Class, SuperClassName)
-
Extracts the name,
SuperClassName
, of the superclass of classClass
. - classInterfaces(Class, Interfaces)
-
Extracts a list,
Interfaces
, of the direct superinterfaces of the classClass
. - classMethods(Class, Methods)
-
Extracts a list,
Methods
, of the methods declared in the classClass
. - classAttributes(Class, Attributes)
-
Extracts a list,
Attributes
, of the attributes of the classClass
.Each attribute is represented as a functor application of the form
attribute(AttributeName, AttributeContents)
, whereAttributeName
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 nameMemberName
and descriptorMemberDescriptor
. This assertion does not consider members declared in the superclasses or superinterfaces ofClass
.
- classDeclaresStrictField(Class, FieldName, FieldDescriptor)
-
Asserts that a class,
Class
, declares a field with nameFieldName
and descriptorFieldDescriptor
, and that field has itsACC_STRICT
flag set.
- classDefiningLoader(Class, Loader)
-
Extracts the defining class loader,
Loader
, of the classClass
. - 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 loaderInitiatingLoader
isClassDefinition
. - methodName(Method, Name)
-
Extracts the name,
Name
, of the methodMethod
. - methodAccessFlags(Method, AccessFlags)
-
Extracts the access flags,
AccessFlags
, of the methodMethod
. - methodDescriptor(Method, Descriptor)
-
Extracts the descriptor,
Descriptor
, of the methodMethod
. - methodAttributes(Method, Attributes)
-
Extracts a list,
Attributes
, of the attributes of the methodMethod
.Each attribute is represented as a functor application of the form
attribute(AttributeName, AttributeContents)
, whereAttributeName
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 classClass
is notfinal
. - isStatic(Method, Class)
-
True iff
Method
in classClass
isstatic
. - isNotStatic(Method, Class)
-
True iff
Method
in classClass
is notstatic
. - isPrivate(Method, Class)
-
True iff
Method
in classClass
isprivate
. - isNotPrivate(Method, Class)
-
True iff
Method
in classClass
is notprivate
. - isProtected(MemberClass, MemberName, MemberDescriptor)
-
True iff there is a member named
MemberName
with descriptorMemberDescriptor
in the classMemberClass
and it isprotected
. - isNotProtected(MemberClass, MemberName, MemberDescriptor)
-
True iff there is a member named
MemberName
with descriptorMemberDescriptor
in the classMemberClass
and it is notprotected
. - parseFieldDescriptor(Descriptor, Type)
-
Converts a field descriptor,
Descriptor
, into the corresponding verification typeType
(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 methodMethod
inClass
, as well as the maximum operand stack size,MaxStack
, the maximal number of local variables,FrameSize
, the exception handlers,Handlers
, and the stack mapStackMap
.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
andClass2
are the same. - differentPackageName(Class1, Class2)
-
True iff the package names of
Class1
andClass2
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:
- a class
- a method
- the declared return type of the method
- the instructions in a method
- the maximal size of the operand stack
- a list of exception handlers
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 theClass
orMethod
term would force us to completely specify the format for a Prolog term representing theclass
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:
Its first operand,
CP
, refers to a constant pool entry denoting a field whose declared type isFieldType
that is a member of a classFieldClassName
.FieldClassName
must not be an array type.Either:
The referenced field, if it is declared by the current class, does not have its
ACC_STRICT
flag set.One can validly pop types matching
FieldType
andFieldClassName
off the incoming operand stack yielding the outgoing type state.protected
fields are subject to additional checks (4.10.1.8).
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
.)
Or:
- If the instruction occurs in an instance initialization method of
the class
FieldClassName
and assigns to a field declared by the class, then one can validly pop types matchingFieldType
anduninitializedThis
off the incoming operand stack yielding the outgoing type state. This allows instance fields ofthis
that are declared in the current class, includingACC_STRICT
final
fields, to be assigned prior to complete initialization ofthis
.
- If the instruction occurs in an instance initialization method of
the class
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.
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 aSpeculativeClassLoadingError
. For now, we'll stick with usingClassCircularityError
in both cases.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 aClassFormatError
.Otherwise, if the purported representation is not of a supported major or minor version (4.1), derivation throws an
UnsupportedClassVersionError
.UnsupportedClassVersionError
, a subclass ofClassFormatError
, was introduced in JDK 1.2 to enable easy identification of aClassFormatError
caused by an attempt to load a class whose representation uses an unsupported version of theclass
file format. In JDK 1.1 and earlier, an instance ofNoClassDefFoundError
orClassFormatError
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 anaccess_flags
item which has theACC_MODULE
flag set.
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. OnlyObject
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 anIncompatibleClassChangeError
.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 anIncompatibleClassChangeError
.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 anIncompatibleClassChangeError
: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'sPermittedSubclasses
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 anIncompatibleClassChangeError
.
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 anIncompatibleClassChangeError
: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'sPermittedSubclasses
attribute refers to a class or interface with the name N.
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 thedescriptors
array of theLoadableDescriptors
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 aClassCircularityError
. 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 theClassCircularityError
.
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:
A class or interface is completely loaded before
it is linkedany linking activities for that class or interface take place.A class or interface is completely verified and prepared before it is initialized.
Errors detected during linkage are thrown at a point in the program where some action is taken by the program that might, directly or indirectly, require
linkage to the class or interfacethe linking activity involved in the error.A symbolic reference to a dynamically-computed constant is not resolved until either (i) an ldc, ldc_w, or ldc2_w instruction that refers to it is executed, or (ii) a bootstrap method that refers to it as a static argument is invoked.
A symbolic reference to a dynamically-computed call site is not resolved until a bootstrap method that refers to it as a static argument is invoked.
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 = value2value1 and value2 are the sameif_acmpne succeeds if and only if
value1 ≠ value2value1 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
, orshort
, the values are the same if a comparison viaif_icmpeq
would succeed (6.5.if_icmp_cond).For fields of type
long
, the values are the same if a comparison vialcmp
would produce 0 (6.5.lcmp).For fields of type
float
, the values are the same if, after applying the conversion defined by the methodFloat.floatToRawIntBits
, a comparison viaif_icmpeq
would succeed.For fields of type
double
, the values are the same if, after applying the conversion defined by the methodDouble.doubleToRawLongBits
, a comparison vialcmp
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:
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:
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.
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.
Otherwise, if C is an interface and the class
Object
contains a declaration of apublic
instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.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 typelong
ordouble
, in local variables 1 and 2), and so on. The new frame is then made current, and the Java Virtual Machinepc
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 issynchronized
, 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 thenative
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 anIncompatibleClassChangeError
. - Run-time Exceptions
-
Otherwise, if objectref is
null
, the invokespecial instruction throws aNullPointerException
.Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects an
abstract
method, invokespecial throws anAbstractMethodError
.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 anUnsatisfiedLinkError
.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 anIncompatibleClassChangeError
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 anAbstractMethodError
. - 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
anddouble
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 aNullPointerException
.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 ofsynchronized
methods, although they can be used to provide equivalent locking semantics. Monitor entry on invocation of asynchronized
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
andObject.notify
). These operations are supported in the standard packagejava.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
instanceidentity 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 aNullPointerException
.Otherwise, if objectref is a value object, or the thread that executes monitorexit is not the owner of the monitor associated with the
instanceidentity object referenced by objectref, monitorexit throws anIllegalMonitorStateException
.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 ofsynchronized
methods, although they can be used to provide equivalent locking semantics.The Java Virtual Machine supports exceptions thrown within
synchronized
methods andsynchronized
statements differently:Monitor exit on normal
synchronized
method completion is handled by the Java Virtual Machine's return instructions. Monitor exit on abruptsynchronized
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 thesynchronized
statement is achieved using the Java Virtual Machine's exception handling mechanism (3.14).