This document describes changes to the Java Virtual Machine Specification, as modified by the Better-defined JVM Class File Validation JEP and JVM Types Cleanup, to support value objects, a preview feature introduced by a draft JEP.
A companion documents describes language changes.
Key changes include:
value
class declarations, with special validation rules (4.1, 4.5, 4.6)Repurposing the
ACC_SUPER
flag to indicateidentity
classes, along with checks for consistent use ofvalue
andidentity
(4.1, 5.3.5)Special
value
class instance creation methods to provide a standard way to encodevalue
class constructors (2.9.4, 4.6, 4.9.1)New
aconst_init
andwithfield
opcodes, to support creation of value objects (4.9.1, 4.10.1.9.aconst_init, 4.10.1.9.withfield, 6.5.aconst_init, 6.5.withfield)Custom behavior for
if_acmpeq
,if_acmpne
,monitorenter
, andmonitorexit
when applied to value objects (6.5.if_acmp_cond, 6.5.monitorenter, 6.5.monitorexit)Rejecting use of
new
with a value class (6.5.new)
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:
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, an instance of the class
Object
, or an array. These objects can mutate their
instance fields or components and are associated with a synchronization
monitor.
Other objects, called value objects, have no identity; the
same object may be created multiple times, independently. A value object
is always an instance of a value
class. These objects have
immutable instance fields and cannot be used for synchronization. A Java
Virtual Machine implementation can sometimes inline a value
object, avoiding the memory and indirection overhead usually associated
with references.
A reference value typically belongs to multiple reference types, which may be either of the following:
A standard 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 standard reference type may be called a class type if it names a class. A standard reference type may be called an interface type if it names an interface.
An
array typearray 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 mayitself 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 be 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 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
.
2.9 Special Methods
2.9.1 Instance Initialization Methods
A class has zero or more instance initialization methods,
used to initialize instances of newly-allocated
identity objects that belong to the class. Each typically
corresponds to a constructor written in the Java programming
language.
If a an identity
class does
not have an instance initialization method, its instances cannot be
initialized or used.
An instance initialization method is declared with the special name
<init>
.
An instance initialization method may not be declared in a
value
class or an interface (4.6).
The declaration and use of an instance initialization method is
constrained by the Java Virtual Machine. For the declaration, the
method's access_flags
item, descriptor, and
code
array are constrained (4.6, 4.9.2). For a use, an instance initialization
method may be invoked only by the invokespecial instruction on
an uninitialized class instance (4.9.1, 4.9.2).
Because the name
<init>
is not a valid identifier in the Java programming language, it cannot be used directly in a program written in the Java programming language.
2.9.4 value
Class Instance
Creation Methods
Design discussion: this section introduces a new kind of special
method, a value
class instance creation method,
with its own special name, <vnew>
. It follows the
pattern of 2.9.1 and 2.9.2.
value
class instance creation methods are intended as a
compilation target for value
class constructors, providing
a standard API point for instance creation without language compilers
needing to introduce an arbitrary (often mangled) name. The methods are
invoked with invokestatic.
While there may be other uses for static factory methods with
standardized names in the future, we anticipate that such a use would
introduce a different special name, readily distinguishable and adhering
to its own rules and conventions. It would be reasonable, for example,
for a value
class to declare both a class instance creation
method and this alternative kind of factory method. The
<foo>
namespace remains reserved for any such future
uses.
As an alternative naming scheme, we could re-use
<init>
but give the method a non-void
return type. This would be convenient for tools that are happy to treat
all constructor encodings similarly, but inconvenient for tools that
need to distinguish between instance initialization
<init>
methods and value
class instance
creation <init>
methods (see, for example, 4.10.1.9.invokespecial).
A non-abstract
value
class may declare zero
or more value
class instance creation methods.
Each typically corresponds to a constructor written in the Java
programming language. These methods return instances of the
value
class, created, for example, via the
aconst_init and withfield instructions.
A value
class instance creation method is declared with
the special name <vnew>
.
A value
class instance creation method may not be
declared in an identity class, an abstract class, or an interface (4.6).
The declaration and use of a value
class instance
creation method is constrained by the Java Virtual Machine. For the
declaration, the method's access_flags
item and descriptor
are constrained (4.6). For a use, a
value
class instance creation method may be invoked only by
the invokestatic instruction (4.9.1).
Because the name
<vnew>
is not a valid identifier in the Java programming language, it cannot be used directly in a program written in the Java programming language.
It may make sense to swap this new section with 2.9.3, with associated renumbering of cross references.
2.11 Instruction Set Summary
2.11.2 Load and Store Instructions
The load and store instructions transfer values between the local variables (2.6.1) and the operand stack (2.6.2) of a Java Virtual Machine frame (2.6):
Load a local variable onto the operand stack: iload, iload_<n>, lload, lload_<n>, fload, fload_<n>, dload, dload_<n>, aload, aload_<n>.
Store a value from the operand stack into a local variable: istore, istore_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>.
Load a constant on to the operand stack: bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, aconst_init, iconst_m1, iconst_<i>, lconst_<l>, fconst_<f>, dconst_<d>.
Gain access to more local variables using a wider index, or to a larger immediate operand: wide.
Instructions that access fields of objects and elements of arrays (2.11.5) also transfer data to and from the operand stack.
Instruction mnemonics shown above with trailing letters between angle
brackets (for instance, iload_<n>) denote families of
instructions (with members iload_0, iload_1,
iload_2, and iload_3 in the case of
iload_<n>). Such families of instructions are
specializations of an additional generic instruction (iload)
that takes one operand. For the specialized instructions, the operand is
implicit and does not need to be stored or fetched. The semantics are
otherwise the same (iload_0 means the same thing as
iload with the operand 0). The letter between the
angle brackets specifies the type of the implicit operand for that
family of instructions: for <n>, a nonnegative integer;
for <i>, an int
; for <l>, a
long
; for <f>, a float
; and for
<d>, a double
.
This notation for instruction families is used throughout this specification.
2.11.5 Object Creation and Manipulation
Although both class instances and arrays are objects, the Java Virtual Machine creates and manipulates class instances and arrays using distinct sets of instructions:
Create a new class instance: new, withfield.
Create a new array: newarray, anewarray, multianewarray.
Access fields of classes (
static
fields, known as class variables) and fields of class instances (non-static
fields, known as instance variables): getstatic, putstatic, getfield, putfield.Load an array component onto the operand stack: baload, caload, saload, iaload, laload, faload, daload, aaload.
Store a value from the operand stack as an array component: bastore, castore, sastore, iastore, lastore, fastore, dastore, aastore.
Get the length of array: arraylength.
Check properties of class instances or arrays: instanceof, checkcast.
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 must have 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 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
class
file must not depend on the preview features of Java SE N unless the Java Virtual Machine conforms to Java SE N and the preview features of Java SE N are enabled.If the Java Virtual Machine conforms to some other version of Java SE, such as Java SE N+1, the class file is not valid.
A
class
file that does not depend on the preview features of any Java SE release is valid regardless of whether the preview features of Java SE N are enabled. - constant_pool_count
-
The value of the
constant_pool_count
item is equal to the number of entries in 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_IDENTITY
0x0020 Declared as an identity
class or interface.ACC_VALUE
0x0040 Declared as a value
class or interface.ACC_INTERFACE
0x0200 Is an interface, not a class. ACC_ABSTRACT
0x0400 Declared abstract
; must not be instantiated.ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. ACC_ANNOTATION
0x2000 Declared as an annotation type. ACC_ENUM
0x4000 Declared as an enum
type.ACC_MODULE
0x8000 Is a module, not a class or interface. In a
class
file with major version 53 or later, theACC_MODULE
flag indicates that thisclass
file defines a module, not a class or interface. In aclass
file with major version less than 53, the 0x8000 bit is ignored, and theACC_MODULE
flag is considered not to be set. If theACC_MODULE
flag is set, then no other flag in Table 4.1-B may be set.The
ACC_INTERFACE
flag indicates that thisclass
file defines an interface, not a module or class. If theACC_INTERFACE
flag is set, theACC_ABSTRACT
flag must also be set, and theACC_FINAL
,ACC_ENUM
, andACC_MODULE
flags must not be set.If neither the
ACC_INTERFACE
flag nor theACC_MODULE
flag is set, thisclass
file defines a class, not a module or interface. In this case, any of the other flags in Table 4.1-B may be set exceptACC_ANNOTATION
.The
ACC_FINAL
flag indicates that this class cannot be extended by another class. If theACC_FINAL
flag is set, theACC_ABSTRACT
flag must not be set.In a
class
file with version number 61.65535, theACC_IDENTITY
flag indicates that this class or interface is anidentity
class or anidentity
interface. For such a class or interface, all instances (of a class directly or of any subclasses) are identity objects (2.4). In aclass
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 otherwise theACC_IDENTITY
flag is considered not to be set.Thus, all classes declared with version numbers other than 61.65535 are
identity
classes. Interfaces, on the other hand, by default are neitheridentity
interfaces norvalue
interfaces.Historically, the value 0x0020 was used to indicate
ACC_SUPER
, which affected the semantics of any invokespecial instructions (6.5.invokespecial) appearing in the class. In Java SE 8, 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
.In a
class
file with version number 61.65535, theACC_VALUE
flag indicates that this class is avalue
class or avalue
interface. For such a class or interface, all instances (of a class directly or of any subclasses) are value objects (2.4). In aclass
file with any other version number, the 0x0040 bit is ignored, and theACC_VALUE
flag is considered not to be set.If the
ACC_VALUE
flag is set, one of theACC_FINAL
orACC_ABSTRACT
flags must also be set.The value
0x0040
is interpreted asACC_VOLATILE
when applied to a field, and asACC_BRIDGE
when applied to a method.A
ClassFile
structure must have no more than one of itsACC_IDENTITY
andACC_VALUE
flags set.A class or interface may have neither its
ACC_IDENTITY
flag nor itsACC_VALUE
flag set. Such a class or interface may be extended or implemented by both kinds of classes. Value object instances will be created without executing any instance initialization method of the class (2.9.1).If a class other than
java/lang/Object
has neither itsACC_IDENTITY
flag nor itsACC_VALUE
flag set, then itsACC_ABSTRACT
flag must be set.The
Object
class is unique in that identity object instances of the class may be created via new (6.5.new) even though the class is not declared anidentity
class. This special treatment allows the class to be extended byvalue
classes.The
ACC_SYNTHETIC
flag indicates that this class or interface was generated by a compiler and does not appear in source code.The
ACC_ANNOTATION
flag indicates that this interface is declared as an annotation interface (JLS §9.6). If 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 are ignored by Java Virtual Machine implementations.Historically, the value 0x0020 was used to indicate
ACC_SUPER
, which affected the semantics of any invokespecial instructions (6.5.invokespecial) appearing in the class or interface. In Java SE 8, theACC_SUPER
semantics became mandatory, regardless of the setting ofACC_SUPER
or theclass
file version number, and the flag no longer had any effect. - this_class
-
The value of the
this_class
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure (4.4.1) referencing a class or interface name.For a module, the referenced name must be
module-info
.For a class or interface, the
this_class
item represents the class or interface defined by thisclass
file. - super_class
-
For a module or a class named
java/lang/Object
, the value of thesuper_class
item must be 0.For a class with any other name, the value of the
super_class
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure referencing a class or interface name.For an interface, the value of the
super_class
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure referencing the namejava/lang/Object
.The
super_class
item represents the direct superclass of the class or interface defined by thisclass
file.The class
Object
has no direct superclass. Interfaces effectively haveObject
as their direct superclass. - interfaces_count
-
The value of the
interfaces_count
item gives the number of direct superinterfaces of this class or interface.For a module,
interfaces_count
must be 0. - interfaces[]
-
Each value in the
interfaces
array must be a valid index into theconstant_pool
table. Theconstant_pool
entry at each value ofinterfaces[i]
, where 0 ≤ i <interfaces_count
, must be aCONSTANT_Class_info
structure referencing a class or interface name.The
interfaces
array represents each interface that is a direct superinterface of this class or interface, in the left-to-right order given in the source for the class or interface. - fields_count
-
The value of the
fields_count
item gives the number offield_info
structures in thefields
table. Thefield_info
structures represent all fields, both class variables and instance variables, declared by this class or interface.For a module,
fields_count
must be 0. - fields[]
-
Each value in the
fields
table must be 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.For a module,
methods_count
must be 0. - 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.The
method_info
structures represent all methods declared by this class or interface, including instance methods, class methods, instance initialization methods (2.9.1), and any class or interface initialization method (2.9.2). 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 nonstandard attributes in the
attributes
table of aClassFile
structure are given in 4.7.1.
4.2 Names
4.2.2 Unqualified Names
Names of methods, fields, local variables, and formal parameters are
stored as unqualified names. An unqualified name must contain
at least one Unicode code point and must not contain any of the ASCII
characters .
;
[
/
(that is, period or semicolon or left square bracket or forward
slash).
Method names are further constrained so that, with the exception of
the special method names <init>
,
and <clinit>
, and
<vnew>
(2.9), they
must not contain the ASCII characters <
or
>
(that is, left angle bracket or right angle
bracket).
4.4 The Constant Pool
4.4.8 The CONSTANT_MethodHandle_info
Structure
Design discussion: the withfield and aconst_init
instructions may justify new forms of
CONSTANT_MethodHandle
, but for now no changes are made to
reference_kind
.
The CONSTANT_MethodHandle_info
structure is used to
represent a method handle:
CONSTANT_MethodHandle_info {
u1 tag;
u1 reference_kind;
u2 reference_index;
}
The items of the CONSTANT_MethodHandle_info
structure
are the following:
- tag
-
The
tag
item has the valueCONSTANT_MethodHandle
(15). - reference_kind
-
The value of the
reference_kind
item must be in the range 1 to 9. The value denotes the kind of this method handle, which characterizes its bytecode behavior (5.4.3.5). - reference_index
-
The value of the
reference_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be as follows:If the value of the
reference_kind
item is 1 (REF_getField
), 2 (REF_getStatic
), 3 (REF_putField
), or 4 (REF_putStatic
), then theconstant_pool
entry at that index must be aCONSTANT_Fieldref_info
structure (4.4.2).The
reference_index
item represents a field for which a method handle is to be created.If the value of the
reference_kind
item is 5 (REF_invokeVirtual
) or 8 (REF_newInvokeSpecial
), then theconstant_pool
entry at that index must be aCONSTANT_Methodref_info
structure (4.4.2).The
reference_index
item represents a class's method or constructor (2.9.1) for which a method handle is to be created.If the value of the
reference_kind
item is 6 (REF_invokeStatic
) or 7 (REF_invokeSpecial
), then if theclass
file version number is less than 52.0, theconstant_pool
entry at that index must be aCONSTANT_Methodref_info
structure; if theclass
file version number is 52.0 or above, theconstant_pool
entry at that index must be either aCONSTANT_Methodref_info
structure or aCONSTANT_InterfaceMethodref_info
structure (4.4.2).The
reference_index
item represents a class's or interface's method for which a method handle is to be created.If the value of the
reference_kind
item is 9 (REF_invokeInterface
), then theconstant_pool
entry at that index must be aCONSTANT_InterfaceMethodref_info
structure.The
reference_index
item represents an interface's method for which a method handle is to be created.
If the value of the
reference_kind
item is 5 (REF_invokeVirtual
),6 (7 (REF_invokeStatic
),REF_invokeSpecial
), or 9 (REF_invokeInterface
), the name of the method represented by aCONSTANT_Methodref_info
structure or aCONSTANT_InterfaceMethodref_info
structure must not be<init>
or<vnew>
.If the value of the reference_kind item is 6 (
REF_invokeStatic
), the name of the method represented by aCONSTANT_Methodref_info
structure or aCONSTANT_InterfaceMethodref_info
structure must not be<init>
.If the value is 8 (
REF_newInvokeSpecial
), the name of the method represented by aCONSTANT_Methodref_info
structure must be<init>
.In no case may the name be
<clinit>
, becauseMethodref
andInterfaceMethodref
structures that reference that name are already prohibited (4.4.2).
4.4.10 The CONSTANT_Dynamic_info
and
CONSTANT_InvokeDynamic_info
Structures
Most structures in the constant_pool
table represent
entities directly, by combining names, descriptors, and values recorded
statically in the table. In contrast, the
CONSTANT_Dynamic_info
and
CONSTANT_InvokeDynamic_info
structures represent entities
indirectly, by pointing to code which computes an entity dynamically.
The code, called a bootstrap method, is invoked by the Java
Virtual Machine during resolution of symbolic references derived from
these structures (5.1, 5.4.3.6).
Each structure specifies a bootstrap method as well as an auxiliary name
and type that characterize the entity to be computed. In more
detail:
The
CONSTANT_Dynamic_info
structure is used to represent a dynamically-computed constant, an arbitrary value that is produced by invocation of a bootstrap method in the course of an ldc instruction (6.5.ldc), among others. The auxiliary type specified by the structure constrains the type of the dynamically-computed constant.The
CONSTANT_InvokeDynamic_info
structure is used to represent a dynamically-computed call site, an instance ofjava.lang.invoke.CallSite
that is produced by invocation of a bootstrap method in the course of an invokedynamic instruction (6.5.invokedynamic). The auxiliary type specified by the structure constrains the method type of the dynamically-computed call site.
CONSTANT_Dynamic_info {
u1 tag;
u2 bootstrap_method_attr_index;
u2 name_and_type_index;
}
CONSTANT_InvokeDynamic_info {
u1 tag;
u2 bootstrap_method_attr_index;
u2 name_and_type_index;
}
The items of these structures are as follows:
- tag
-
The
tag
item of aCONSTANT_Dynamic_info
structure has the valueCONSTANT_Dynamic
(17).The
tag
item of aCONSTANT_InvokeDynamic_info
structure has the valueCONSTANT_InvokeDynamic
(18). - bootstrap_method_attr_index
-
The value of the
bootstrap_method_attr_index
item must be a valid index into thebootstrap_methods
table of theBootstrapMethods
attribute of thisClassFile
structure (4.7.23).CONSTANT_Dynamic_info
structures are unique in that they are syntactically allowed to refer to themselves via the bootstrap method table. Rather than mandating that such cycles are detected when classes are loaded (a potentially expensive check), we permit cycles initially but mandate a failure at resolution (5.4.3.6). - name_and_type_index
-
The value of the
name_and_type_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_NameAndType_info
structure (4.4.6). Thisconstant_pool
entry indicates a name and descriptor.In a
CONSTANT_Dynamic_info
structure, the indicated descriptor must be a field descriptor (4.3.2).In a
CONSTANT_InvokeDynamic_info
structure, the indicated name must be a valid method name (4.2.2) and must not be<clinit>
,or<init>
, or<vnew>
. The indicated descriptor must be a method descriptor (4.3.3).We could allow
<vnew>
here, but the precedent seems to be to avoid any special method names when using invokedynamic.
4.5 Fields
Each field is described by a field_info
structure.
A ClassFile
structure must not declare two fields with
the same name and descriptor (4.3.2).
The structure has the following format:
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
The items of the field_info
structure are as
follows:
- access_flags
-
The value of the
access_flags
item is a mask of flags used to denote access permission to and properties of this field. The interpretation of each flag, when set, is specified in Table 4.5-A.Table 4.5-A. Field access and property flags
Flag Name Value Interpretation ACC_PUBLIC
0x0001 Declared public
; may be accessed from outside its package.ACC_PRIVATE
0x0002 Declared private
; accessible only within the defining class and other classes belonging to the same nest (5.4.4).ACC_PROTECTED
0x0004 Declared protected
; may be accessed within subclasses.ACC_STATIC
0x0008 Declared static
.ACC_FINAL
0x0010 Declared final
; never directly assigned to after object construction (JLS §17.5).ACC_VOLATILE
0x0040 Declared volatile
; cannot be cached.ACC_TRANSIENT
0x0080 Declared transient
; not written or read by a persistent object manager.ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. ACC_ENUM
0x4000 Declared as an element of an enum
class.Fields of classes may set any of the flags in Table 4.5-A. However, each field of a class must have at most one of its
ACC_PUBLIC
,ACC_PRIVATE
, 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 an
abstract
class that is not anidentity
class, each field must have itsACC_STATIC
flag set.In a non-
abstract
value
class, each field must have at least one of itsACC_STATIC
orACC_FINAL
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 are 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 (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).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 nonstandard 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.
A ClassFile
structure must not declare two methods with
the same name and descriptor (4.3.3).
The structure has the following format:
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
The items of the method_info
structure are as
follows:
- access_flags
-
The value of the
access_flags
item is a mask of flags used to denote access permission to and properties of this method. The interpretation of each flag, when set, is specified in Table 4.6-A.Table 4.6-A. Method access and property flags
Flag Name Value Interpretation ACC_PUBLIC
0x0001 Declared public
; may be accessed from outside its package.ACC_PRIVATE
0x0002 Declared private
; accessible only within the defining class and other classes belonging to the same nest (5.4.4).ACC_PROTECTED
0x0004 Declared protected
; may be accessed within subclasses.ACC_STATIC
0x0008 Declared static
.ACC_FINAL
0x0010 Declared final
; must not be overridden (5.4.5).ACC_SYNCHRONIZED
0x0020 Declared synchronized
; invocation is wrapped by a monitor use.ACC_BRIDGE
0x0040 A bridge method, generated by the compiler. ACC_VARARGS
0x0080 Declared with variable number of arguments. ACC_NATIVE
0x0100 Declared native
; implemented in a language other than the Java programming language.ACC_ABSTRACT
0x0400 Declared abstract
; no implementation is provided.ACC_STRICT
0x0800 Declared strictfp
; floating-point mode is FP-strict.ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. A method named
<init>
(2.9.1) must have at most one of itsACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set, and may also have itsACC_VARARGS
,ACC_STRICT
, andACC_SYNTHETIC
flags set, but must not have any of the other flags in Table 4.6-A set.A method named
<clinit>
(2.9.2) may have any of the flags in Table 4.6-A set, in any combination, but all flags exceptACC_STATIC
,ACC_STRICT
, andACC_SYNTHETIC
are treated by the Java Virtual Machine as if they were not set. In aclass
file whose version number is 51.0 or greater, theACC_STATIC
flag must be set; in aclass
file whose version number is less than 51.0, theACC_STATIC
flag is treated by the Java Virtual Machine as if it were set.A method named
<vnew>
(2.9.3) must have itsACC_STATIC
flag set, must not have itsACC_ABSTRACT
flag set, must have at most one of itsACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set, and may have any of the other flags in Table 4.6-A set.Methods of classes with names other than
<init>
,and<clinit>
, and<vnew>
may have any of the flags in Table 4.6-A set. However, each such method must have at most one of itsACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set (JLS §8.4.3).In a class that is not an
identity
class, a method that has itsACC_SYNCHRONIZED
flag set must also have itsACC_STATIC
flag set.Methods of interfaces with names other than
<clinit>
must not have theirACC_PROTECTED
,ACC_FINAL
,ACC_SYNCHRONIZED
, andACC_NATIVE
flags set (JLS §9.4); exactly one of theACC_PUBLIC
orACC_PRIVATE
flags must be set. They may have any of the other flags in Table 4.6-A set. In aclass
file whose version number is less than 52.0, each method of an interface with a name other than<clinit>
must have itsACC_PUBLIC
andACC_ABSTRACT
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
,ACC_NATIVE
, orACC_STRICT
flags set.The
ACC_BRIDGE
flag is used to indicate a bridge method generated by a compiler for the Java programming language.The
ACC_VARARGS
flag indicates that this method takes a variable number of arguments at the source code level.The
ACC_SYNTHETIC
flag indicates that this method was generated by a compiler and does not appear in source code, and is not one of the methods named in 4.7.8.All bits of the
access_flags
item not assigned in Table 4.6-A are reserved for future use. They should be set to zero in generatedclass
files and are 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 a valid unqualified method name.A method of a
value
class or an interface must not have the name<init>
.A method of an
abstract
class, anidentity
class, or an interface must not have the name<vnew>
. - descriptor_index
-
The value of the
descriptor_index
item must be a valid index into 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 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 that takes no arguments.If the name of the method is
<vnew>
, then the descriptor must denote a return type that is the type of the current class or interface.
A future edition of this specification may require that the last parameter descriptor of the method descriptor is an array type if the
ACC_VARARGS
flag is set in theaccess_flags
item.A hidden class is incapable of naming its class type in a descriptor. Rather than declaring a
<vnew>
method, a hiddenvalue
class will have to provide a different instance creation mechanism—for example, a static method named$make
. - attributes_count
-
The value of the
attributes_count
item indicates the number of additional attributes of this method. - attributes[]
-
Each value of the
attributes
table must be anattribute_info
structure (4.7).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 nonstandard 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)
which represents the name of the attribute. The value of the
attribute_length
item indicates the length of the
subsequent information in bytes. The length does not include the initial
six bytes that contain the attribute_name_index
and
attribute_length
items.
29 30 attributes are predefined by this
specification. They are listed three times, for ease of navigation:
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 structures of
appropriately-versioned class
files in which they appear,
the names of these predefined attributes are reserved.
Any conditions on the presence of a predefined attribute in an
attributes
table are specified explicitly in the section
which describes the attribute. If no conditions are specified, then the
attribute may appear any number of times in an attributes
table.
The predefined attributes are categorized into two groups according to their purpose:
Nine attributes are critical to correct interpretation of the
class
file by the Java Virtual Machine:ConstantValue
Code
StackMapTable
BootstrapMethods
Module
ModulePackages
ModuleMainClass
NestHost
NestMembers
In a
class
file whose version number is v, each of these attributes must be recognized and correctly read by an implementation of the Java Virtual Machine if the implementation supports version v of 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.2021 attributes are not critical to correct interpretation of theclass
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"):Exceptions
InnerClasses
EnclosingMethod
Synthetic
Signature
Record
SourceFile
SourceDebugExtension
LineNumberTable
LocalVariableTable
LocalVariableTypeTable
Deprecated
RuntimeVisibleAnnotations
RuntimeInvisibleAnnotations
RuntimeVisibleParameterAnnotations
RuntimeInvisibleParameterAnnotations
RuntimeVisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations
AnnotationDefault
MethodParameters
Preload
An implementation of the Java Virtual Machine may use the information that these attributes contain, or otherwise must silently ignore these attributes.
Table 4.7-A. Predefined class
file attributes (by
section)
Attribute | Section | class file |
Java SE |
---|---|---|---|
ConstantValue |
4.7.2 | 45.3 | 1.0.2 |
Code |
4.7.3 | 45.3 | 1.0.2 |
StackMapTable |
4.7.4 | 50.0 | 6 |
Exceptions |
4.7.5 | 45.3 | 1.0.2 |
InnerClasses |
4.7.6 | 45.3 | 1.1 |
EnclosingMethod |
4.7.7 | 49.0 | 5.0 |
Synthetic |
4.7.8 | 45.3 | 1.1 |
Signature |
4.7.9 | 49.0 | 5.0 |
SourceFile |
4.7.10 | 45.3 | 1.0.2 |
SourceDebugExtension |
4.7.11 | 49.0 | 5.0 |
LineNumberTable |
4.7.12 | 45.3 | 1.0.2 |
LocalVariableTable |
4.7.13 | 45.3 | 1.0.2 |
LocalVariableTypeTable |
4.7.14 | 49.0 | 5.0 |
Deprecated |
4.7.15 | 45.3 | 1.1 |
RuntimeVisibleAnnotations |
4.7.16 | 49.0 | 5.0 |
RuntimeInvisibleAnnotations |
4.7.17 | 49.0 | 5.0 |
RuntimeVisibleParameterAnnotations |
4.7.18 | 49.0 | 5.0 |
RuntimeInvisibleParameterAnnotations |
4.7.19 | 49.0 | 5.0 |
RuntimeVisibleTypeAnnotations |
4.7.20 | 52.0 | 8 |
RuntimeInvisibleTypeAnnotations |
4.7.21 | 52.0 | 8 |
AnnotationDefault |
4.7.22 | 49.0 | 5.0 |
BootstrapMethods |
4.7.23 | 51.0 | 7 |
MethodParameters |
4.7.24 | 52.0 | 8 |
Module |
4.7.25 | 53.0 | 9 |
ModulePackages |
4.7.26 | 53.0 | 9 |
ModuleMainClass |
4.7.27 | 53.0 | 9 |
NestHost |
4.7.28 | 55.0 | 11 |
NestMembers |
4.7.29 | 55.0 | 11 |
Record |
4.7.30 | 60.0 | 16 |
Preload |
4.7.31 | 61.65535 | 18 |
Table 4.7-B. Predefined class
file attributes (by
class
file format)
Attribute | class file |
Java SE | Section |
---|---|---|---|
ConstantValue |
45.3 | 1.0.2 | 4.7.2 |
Code |
45.3 | 1.0.2 | 4.7.3 |
Exceptions |
45.3 | 1.0.2 | 4.7.5 |
SourceFile |
45.3 | 1.0.2 | 4.7.10 |
LineNumberTable |
45.3 | 1.0.2 | 4.7.12 |
LocalVariableTable |
45.3 | 1.0.2 | 4.7.13 |
InnerClasses |
45.3 | 1.1 | 4.7.6 |
Synthetic |
45.3 | 1.1 | 4.7.8 |
Deprecated |
45.3 | 1.1 | 4.7.15 |
EnclosingMethod |
49.0 | 5.0 | 4.7.7 |
Signature |
49.0 | 5.0 | 4.7.9 |
SourceDebugExtension |
49.0 | 5.0 | 4.7.11 |
LocalVariableTypeTable |
49.0 | 5.0 | 4.7.14 |
RuntimeVisibleAnnotations |
49.0 | 5.0 | 4.7.16 |
RuntimeInvisibleAnnotations |
49.0 | 5.0 | 4.7.17 |
RuntimeVisibleParameterAnnotations |
49.0 | 5.0 | 4.7.18 |
RuntimeInvisibleParameterAnnotations |
49.0 | 5.0 | 4.7.19 |
AnnotationDefault |
49.0 | 5.0 | 4.7.22 |
StackMapTable |
50.0 | 6 | 4.7.4 |
BootstrapMethods |
51.0 | 7 | 4.7.23 |
RuntimeVisibleTypeAnnotations |
52.0 | 8 | 4.7.20 |
RuntimeInvisibleTypeAnnotations |
52.0 | 8 | 4.7.21 |
MethodParameters |
52.0 | 8 | 4.7.24 |
Module |
53.0 | 9 | 4.7.25 |
ModulePackages |
53.0 | 9 | 4.7.26 |
ModuleMainClass |
53.0 | 9 | 4.7.27 |
NestHost |
55.0 | 11 | 4.7.28 |
NestMembers |
55.0 | 11 | 4.7.29 |
Record |
60.0 | 16 | 4.7.30 |
Preload |
61.65535 | 18 | 4.7.31 |
Table 4.7-C. Predefined class
file attributes (by
location)
Attribute | Location | class file |
---|---|---|
SourceFile |
ClassFile |
45.3 |
InnerClasses |
ClassFile |
45.3 |
EnclosingMethod |
ClassFile |
49.0 |
SourceDebugExtension |
ClassFile |
49.0 |
BootstrapMethods |
ClassFile |
51.0 |
Module ,
ModulePackages , ModuleMainClass |
ClassFile |
53.0 |
NestHost ,
NestMembers |
ClassFile |
55.0 |
Record |
ClassFile |
60.0 |
ConstantValue |
field_info |
45.3 |
Code |
method_info |
45.3 |
Exceptions |
method_info |
45.3 |
RuntimeVisibleParameterAnnotations ,
RuntimeInvisibleParameterAnnotations |
method_info |
49.0 |
AnnotationDefault |
method_info |
49.0 |
MethodParameters |
method_info |
52.0 |
Table 4.7-C (cont.). Predefined class
file attributes
(by location)
Attribute | Location | class file |
---|---|---|
Synthetic |
ClassFile ,
field_info , method_info |
45.3 |
Deprecated |
ClassFile ,
field_info , method_info |
45.3 |
Signature |
ClassFile ,
field_info , method_info ,
record_component_info |
49.0 |
Preload |
ClassFile |
61.65535 |
RuntimeVisibleAnnotations ,
RuntimeInvisibleAnnotations |
ClassFile ,
field_info , method_info ,
record_component_info |
49.0 |
LineNumberTable |
Code |
45.3 |
LocalVariableTable |
Code |
45.3 |
LocalVariableTypeTable |
Code |
49.0 |
StackMapTable |
Code |
50.0 |
RuntimeVisibleTypeAnnotations ,
RuntimeInvisibleTypeAnnotations |
ClassFile ,
field_info , method_info , Code ,
record_component_info |
52.0 |
4.7.6 The InnerClasses
Attribute
...
- inner_class_access_flags
-
The value of the
inner_class_access_flags
item is a mask of flags used to denote access permissions to and properties of class or interface C as declared in the source code from which 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 Declared as an identity
class or interface.ACC_VALUE
0x0040 Declared as a value
class or interface.ACC_INTERFACE
0x0200 Was an interface
in source.ACC_ABSTRACT
0x0400 Marked or implicitly abstract
in source.ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. ACC_ANNOTATION
0x2000 Declared as an annotation interface. ACC_ENUM
0x4000 Declared as an enum
class.All bits of the
inner_class_access_flags
item not assigned in Table 4.7.6-A are reserved for future use. They should be set to zero in generatedclass
files and should be ignored by Java Virtual Machine implementations.
...
4.7.31 The Preload
Attribute
The Preload
attribute is a variable-length attribute in
the attributes
table of a ClassFile
structure
(4.1) in a version 61.65535 class
file. The Preload
attribute indicates to a Java Virtual
Machine implementation that certain classes contain information that may
be of interest during linkage. For example, a value
class
might be listed to facilitate inlining of value objects.
There must be no more than one Preload
attribute in the
attributes
table of a ClassFile
structure.
The Preload
attribute should have the following
format:
Preload_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_classes;
u2 classes[number_of_classes];
}
The items of the Preload_attribute
structure are as
follows:
- attribute_name_index
-
The value of the
attribute_name_index
item is an index into theconstant_pool
table. Theconstant_pool
entry at that index is aCONSTANT_Utf8_info
structure (4.4.7) representing the string "Preload
". - attribute_length
-
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes. - number_of_classes
-
The value of the
number_of_classes
item indicates the number of entries in theclasses
array. - classes[]
-
Each value in the
classes
array should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_Class_info
structure (4.4.1) representing a class or interface.
4.9 Constraints on Java Virtual Machine Code
4.9.1 Static Constraints
The static constraints on the code in a class
file specify how Java Virtual Machine instructions must be laid out in
the code
array, what the operands of individual
instructions must be, and how exception_table
and
StackMapTable
entries reference the code
array
and the constant pool.
The static constraints on the instructions in the code
array are as follows:
Only instances of the instructions documented in 6.5 may appear in the
code
array. Instances of instructions using the reserved opcodes (6.2) or any opcodes not documented in this specification must not appear in thecode
array.If the
class
file version number is 51.0 or above, then neither the jsr opcode nor the jsr_w opcode may appear in thecode
array.If the
class
file version number is not 61.65535, then neither the aconst_init opcode nor the withfield opcode may appear in thecode
array.The opcode of the first instruction in the
code
array begins at index0
.For each instruction in the
code
array except the last, the index of the opcode of the next instruction equals the index of the opcode of the current instruction plus the length of that instruction, including all its operands.The wide instruction is treated like any other instruction for these purposes; the opcode specifying the operation that a wide instruction is to modify is treated as one of the operands of that wide instruction. That opcode must never be directly reachable by the computation.
The last byte of the last instruction in the
code
array must be the byte at indexcode_length - 1
.
The static constraints on the operands of instructions in the
code
array are as follows:
The target of each jump and branch instruction (jsr, jsr_w, goto, goto_w, ifeq, ifne, ifle, iflt, ifge, ifgt, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmple, if_icmplt, if_icmpge, if_icmpgt, if_acmpeq, if_acmpne) must be the opcode of an instruction within this method.
The target of a jump or branch instruction must never be the opcode used to specify the operation to be modified by a wide instruction; a jump or branch target may be the wide instruction itself.
Each target, including the default, of each tableswitch instruction must be the opcode of an instruction within this method.
Each tableswitch instruction must have a number of entries in its jump table that is consistent with the value of its low and high jump table operands, and its low value must be less than or equal to its high value.
No target of a tableswitch instruction may be the opcode used to specify the operation to be modified by a wide instruction; a tableswitch target may be a wide instruction itself.
Each target, including the default, of each lookupswitch instruction must be the opcode of an instruction within this method.
Each lookupswitch instruction must have a number of match-offset pairs that is consistent with the value of its npairs operand. The match-offset pairs must be sorted in increasing numerical order by signed match value.
No target of a lookupswitch instruction may be the opcode used to specify the operation to be modified by a wide instruction; a lookupswitch target may be a wide instruction itself.
The operands of each ldc instruction and each ldc_w instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be loadable (4.4), and not any of the following:An entry of kind
CONSTANT_Long
orCONSTANT_Double
.An entry of kind
CONSTANT_Dynamic
that references aCONSTANT_NameAndType_info
structure which indicates a descriptor ofJ
(denotinglong
) orD
(denotingdouble
).
The operands of each ldc2_w instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be loadable, and in particular one of the following:An entry of kind
CONSTANT_Long
orCONSTANT_Double
.An entry of kind
CONSTANT_Dynamic
that references aCONSTANT_NameAndType_info
structure which indicates a descriptor ofJ
(denotinglong
) orD
(denotingdouble
).
The operands of each getfield, putfield, withfield, getstatic, and putstatic instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_Fieldref
.The indexbyte operands of each invokevirtual instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_Methodref
.The indexbyte operands of each invokespecial and invokestatic instruction must represent a valid index into the
constant_pool
table. If theclass
file version number is less than 52.0, the constant pool entry referenced by that index must be of kindCONSTANT_Methodref
; if theclass
file version number is 52.0 or above, the constant pool entry referenced by that index must be of kindCONSTANT_Methodref
orCONSTANT_InterfaceMethodref
.The indexbyte operands of each invokeinterface instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_InterfaceMethodref
.The value of the count operand of each invokeinterface instruction must reflect the number of local variables necessary to store the arguments to be passed to the interface method, as implied by the descriptor of the
CONSTANT_NameAndType_info
structure referenced by theCONSTANT_InterfaceMethodref
constant pool entry.The fourth operand byte of each invokeinterface instruction must have the value zero.
The indexbyte operands of each invokedynamic instruction must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_InvokeDynamic
.The third and fourth operand bytes of each invokedynamic instruction must have the value zero.
The method name of the
CONSTANT_Methodref
orCONSTANT_InterfaceMethodref
referenced by one of the instructions invokevirtual, invokestatic, or invokeinterface must not be<init>
.The method name of the
CONSTANT_Methodref
orCONSTANT_InterfaceMethodref
referenced by one of the instructions invokevirtual, invokespecial, or invokeinterface must not be<vnew>
.Only the invokespecial instruction is allowed to invoke an instance initialization method (2.9.1). Only the invokestatic instruction is allowed to invoke a
value
class instance creation method (2.9.4). No instruction is allowed to invoke a class initialization method, because it cannot be referenced (4.4.2)—such methods are only invoked implicitly by the Java Virtual Machine (5.5).The operands of each instanceof, checkcast, aconst_init, new, and anewarray instruction, and the indexbyte operands of each multianewarray instruction, must represent a valid index into the
constant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_Class
.No new instruction may reference a constant pool entry of kindEvery new and aconst_init instruction must reference a constant pool entry of kindCONSTANT_Class
that represents an array type (4.3.2). The new instruction cannot be used to create an array.CONSTANT_Class
that represents a class or interface.No anewarray instruction may reference a constant pool entry of kind
CONSTANT_Class
that represents an array type with more than 254 dimensions.Every multianewarray instruction must reference a constant pool entry of kind
CONSTANT_Class
that represents an array type.A multianewarray instruction must be used only to create an array of a type that has at least as many dimensions as the value of its dimensions operand. That is, while a multianewarray instruction is not required to create all of the dimensions of the array type referenced by its indexbyte operands, it must not attempt to create more dimensions than are in the array type.
The dimensions operand of each multianewarray instruction must not be zero.
The atype operand of each newarray instruction must take one of the values
T_BOOLEAN
(4),T_CHAR
(5),T_FLOAT
(6),T_DOUBLE
(7),T_BYTE
(8),T_SHORT
(9),T_INT
(10), orT_LONG
(11).The index operand of each iload, fload, aload, istore, fstore, astore, iinc, and ret instruction must be a non-negative integer no greater than
max_locals - 1
.The implicit index of each iload_<n>, fload_<n>, aload_<n>, istore_<n>, fstore_<n>, and astore_<n> instruction must be no greater than
max_locals - 1
.The index operand of each lload, dload, lstore, and dstore instruction must be no greater than
max_locals - 2
.The implicit index of each lload_<n>, dload_<n>, lstore_<n>, and dstore_<n> instruction must be no greater than
max_locals - 2
.The indexbyte operands of each wide instruction modifying an iload, fload, aload, istore, fstore, astore, iinc, or ret instruction must represent a non-negative integer no greater than
max_locals - 1
.The indexbyte operands of each wide instruction modifying an lload, dload, lstore, or dstore instruction must represent a non-negative integer no greater than
max_locals - 2
.
The static constraints on the entries in the
exception_table
array are as follows:
The
start_pc
item of each entry must be a valid index into thecode
array and must be the index of the opcode of an instruction.The
end_pc
item of each entry must either be a valid index into thecode
array or must equal thecode_length
item. Ifend_pc
is a valid index into thecode
array, it must be the index of the opcode of an instruction. The value ofend_pc
must be greater than the corresponding value ofstart_pc
.The
handler_pc
item of each entry must be a valid index into thecode
array and must be the index of the opcode of an instruction.The
catch_type
item of each entry must either be 0 or represent a valid index into theconstant_pool
table. Ifcatch_type
is nonzero, the constant pool entry referenced by that index must be of kindCONSTANT_Class
.
The static constraints on the entries in the the entries
table of a StackMapTable
attribute (4.7.4) are as
follows:
Each table entry must match one of the items of the
stack_map_frame
discriminated union.The number of entries in the
entries
table must equal thenumber_of_entries
item of theStackMapTable
attribute.For each verification type in the
locals
orstack
table of any frame type:If the verification type has the form
Object_variable_info
, it must have acpool_index
item that is a valid index into theconstant_pool
table. The constant pool entry referenced by that index must be of kindCONSTANT_Class
.If the verification type has the form
Uninitialized_variable_info
, it must have anoffset
item that is a valid index into thecode
array of theCode
attribute to which thisStackMapTable
belongs. Theoffset
must be the index of the opcode of anew
instruction.
4.9.2 Structural Constraints
The structural constraints on the code in a
class
file specify constraints on relationships between
Java Virtual Machine instructions, exception handlers, and stack maps.
The structural constraints are as follows:
For each stack map table entry, the bytecode offset specified by the frame must be a valid index into the
Code
array, and must be the index of the opcode of an instruction.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.
As noted in 2.3.4 and 2.11.1, the Java Virtual Machine implicitly converts values of types
boolean
,byte
,short
, andchar
to typeint
, allowing instructions expecting values of typeint
to operate on them.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.
No stack map table entry may represent a stack frame with a stack type array of size greater than that implied by the
max_stack
item.No stack map table entry may represent a stack frame with a local variable type array of size less than 0 or greater than that implied by the
max_locals
item.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 an invokespecial instruction names an instance initialization method and 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.
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.However, instance fields of
this
that are declared in the current class may be assigned by putfield before calling any 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.
If there is an uninitialized class instance in a local variable in code protected by an exception handler, then (i) if the handler is inside an
<init>
method, the handler must throw an exception or loop forever; and- if the handler is not inside an
<init>
method, the uninitialized class instance must remain uninitialized.
- if the handler is not inside an
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 value that is the target of an invokevirtual, invokeinterface, or invokespecial instruction (that is, the type of the target reference on the operand stack) must be a subtype (4.10.1.2) of the type specified in the instruction.
The types of the arguments to each method invocation must be subtypes of the types given by the method descriptor (4.3.3), where descriptor types
boolean
,byte
,char
, andshort
are interpreted as typeint
.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 a subtype of the return descriptor of the method (4.3.3).All methods declared to return
void
must use only the return instruction.
The type of every value accessed by a getfield, putfield, or withfield instruction
or modified by a putfield instruction(that is, the type of the target reference on the operand stack) must be a subtype of the type specified in the instruction.The type of every value stored by a putfield, withfield, 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 a subtype of 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 type mentioned in a
catch_type
item of theexception_table
array must beThrowable
or a subtype 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 the class type of the current class or one of its subclasses.In principle, this rule should apply to withfield as well. But since the referenced class of withfield must be a
value
class, there are no possible field references to which it would apply.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 the class type of the current class or one of its subclasses.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.9 Type Checking Instructions
aconst_init
An aconst_init instruction with operand CP
is
type safe iff one can validly push type CP
onto the
incoming operand stack yielding the outgoing type state.
instructionIsTypeSafe(aconst_init(CP), Environment, _Offset, StackFrame,
NextStackFrame, ExceptionStackFrame) :-
validTypeTransition(Environment, [], CP, StackFrame, NextStackFrame),
exceptionStackFrame(StackFrame, ExceptionStackFrame).
withfield
A withfield instruction with operand CP
is type
safe iff its operand, CP
, refers to a constant pool entry
denoting a field whose declared type is FieldType
, as a
member of type FieldClassType
; and one can validly replace
types matching FieldType
and FieldClassType
with FieldClassType
on the incoming operand stack, yielding
the outgoing type state.
instructionIsTypeSafe(withfield(CP), Environment, _Offset, StackFrame,
NextStackFrame, ExceptionStackFrame) :-
CP = field(FieldClassType, _FieldName, FieldDescriptor),
parseFieldDescriptor(FieldDescriptor, FieldType),
validTypeTransition(Environment, [FieldType, FieldClassType],
FieldClassType, StackFrame, NextStackFrame),
exceptionStackFrame(StackFrame, ExceptionStackFrame).
Chapter 5: Loading, Linking, and Initializing
5.3 Creation and Loading
5.3.5 Deriving a Class from a class
File Representation
The following steps are used to derive a Class
object
for the nonarray class or interface C denoted by N
using loader L from a purported representation in
class
file format.
First, the Java Virtual Machine determines whether the attempt to derive a class or interface named N for class loader L is invalid. If so, loading throws a
LinkageError
.An attempt to derive a class or interface named N for class loader L is invalid if one of the following are true:
L has already been recorded as as an initiating loader of a class or interface named N.
L is not the bootstrap class loader (5.3) and N is the reserved name
java/lang/Object
.
The second case, combined with restrictions in 4.1, ensures that there is only one root of the class hierarchy, and the name
java/lang/Object
can reliably be used to refer to it.The Java SE API enforces additional security restrictions that prevent unauthorized attempts to load classes in certain packages, including
java.*
.Otherwise, the Java Virtual Machine attempts to parse the purported representation. However, the purported representation may not in fact be a valid representation of C.
This phase of loading must detect the following errors:
If the purported representation provides a major and minor version number in its 5th through 8th bytes (4.1), but the version number is not supported by this Java Virtual Machine implementation, loading throws an instance of
UnsupportedClassVersionError
.UnsupportedClassVersionError
, a subclass ofClassFormatError
, was introduced 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 is not a valid
class
file ([4]), loading throws an instance ofClassFormatError
.Otherwise, if the purported representation does not actually represent a class or interface named N, loading throws an instance of
NoClassDefFoundError
or an instance of one of its subclasses.This occurs when the purported representation has either a
this_class
item which specifies a name other than N, or 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. Only
Object
has no direct superclass.Note that if C is an interface, its direct superclass is the class
Object
(4.1). The symbolic reference toObject
is resolved just like a reference to any other class.Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:
If any of the superclasses of C is C itself, loading throws a
ClassCircularityError
.Otherwise, if the class or interface named as the direct superclass of C is in fact an interface or a
final
class, loading throws anIncompatibleClassChangeError
.Otherwise, if C is an
identity
class and any superclass of C is avalue
class, or C is avalue
class and any superclass of C is anidentity
class, loading throws anIncompatibleClassChangeError
.Otherwise, if C is a class and some instance method declared in C can override (5.4.5) a
final
instance method declared in a superclass of C, loading throws 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.
Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:
If any of the superinterfaces of C is C itself, loading throws a
ClassCircularityError
.Otherwise, if any of the classes or interfaces named as direct superinterfaces of C is not in fact an interface, loading throws an
IncompatibleClassChangeError
.Otherwise, if C, one of its superclasses, or one of its superinterfaces is an
identity
class or anidentity
interface, and some other of C, one of its superclasses, or one of its superinterfaces is avalue
class or avalue
interface, loading throws anIncompatibleClassChangeError
.
The Java Virtual Machine marks C as having L as its defining class loader and records that L is an initiating loader of C (5.3.4).
5.4 Linking
5.4.3 Resolution
Many Java Virtual Machine instructions -
aconst_init, anewarray,
checkcast, getfield, getstatic,
instanceof, invokedynamic, invokeinterface,
invokespecial, invokestatic, invokevirtual,
ldc, ldc_w, ldc2_w, multianewarray,
new, putfield, and
putstatic, and withfield - rely on
symbolic references in the run-time constant pool. Execution of any of
these instructions requires resolution of the symbolic
reference.
...
5.5 Initialization
Initialization of a class or interface consists of executing its class or interface initialization method (2.9.2).
A class or interface C may be initialized only as a result of:
The execution of any one of the Java Virtual Machine instructions new, aconst_init, getstatic, putstatic, or invokestatic that references C (6.5.new, 6.5.aconst_init, 6.5.getstatic, 6.5.putstatic, 6.5.invokestatic).
Upon execution of a new or aconst_init instruction, the class to be initialized is the class referenced by the instruction.
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface to be initialized is the class or interface that declares the resolved field or method.
The first invocation of a
java.lang.invoke.MethodHandle
instance which was the result of method handle resolution (5.4.3.5) for a method handle of kind 2 (REF_getStatic
), 4 (REF_putStatic
), 6 (REF_invokeStatic
), or 8 (REF_newInvokeSpecial
).This implies that the class of a bootstrap method is initialized when the bootstrap method is invoked for an invokedynamic instruction (6.5.invokedynamic), as part of the continuing resolution of the call site specifier.
Invocation of certain reflective methods in the class library (2.12), for example, in class
Class
or in packagejava.lang.reflect
.If C is a class, the initialization of one of its subclasses.
If C is an interface that declares a non-
abstract
, non-static
method, the initialization of a class that implements C directly or indirectly.Its designation as the initial class or interface at Java Virtual Machine startup (5.2).
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
Because the Java Virtual Machine is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface. The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization by using the following procedure. It assumes that the class or interface has already been verified and prepared, and that the class or interface contains state that indicates one of four situations:
This class or interface is verified and prepared but not initialized.
This class or interface is being initialized by some particular thread.
This class or interface is fully initialized and ready for use.
This class or interface is in an erroneous state, perhaps because initialization was attempted and failed.
For each class or interface C, there is a unique
initialization lock LC. The mapping from C to
LC is left to the discretion of the Java Virtual Machine
implementation. For example, LC could be the Class
object for C, or the monitor associated with that
Class
object. The procedure for initializing C is
then as follows:
Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.
If C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this procedure.
Thread interrupt status is unaffected by execution of the initialization procedure.
If C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.
If C indicates that it has already been initialized, then no further action is required. Release LC and complete normally.
If C is in an erroneous state, then initialization is not possible. Release LC and throw a
NoClassDefFoundError
.Otherwise, record the fact that initialization of the
Class
object for C is in progress by the current thread, and release LC.Then, initialize each
final
static
field of C with the constant value in itsConstantValue
attribute (4.7.2), in the order the fields appear in theClassFile
structure.Next, if C is a class rather than an interface, then let SC be its superclass and let SI1, ..., SIn be all superinterfaces of C (whether direct or indirect) that declare at least one non-
abstract
, non-static
method. The order of superinterfaces is given by a recursive enumeration over the superinterface hierarchy of each interface directly implemented by C. For each interface I directly implemented by C (in the order of theinterfaces
array of C), the enumeration recurs on I's superinterfaces (in the order of theinterfaces
array of I) before returning I.For each S in the list [ SC, SI1, ..., SIn ], if S has not yet been initialized, then recursively perform this entire procedure for S. If necessary, verify and prepare S first.
If the initialization of S completes abruptly because of a thrown exception, then acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing S.
Next, determine whether assertions are enabled for C by querying its defining class loader.
Next, if C declares a class or interface initialization method, execute that method.
If the execution of the class or interface initialization method completes normally, then acquire LC, label the
Class
object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.Otherwise, the class or interface initialization method must have completed abruptly by throwing some exception E. If the class of E is not
Error
or one of its subclasses, then create a new instance of the classExceptionInInitializerError
with E as the argument, and use this object in place of E in the following step. If a new instance ofExceptionInInitializerError
cannot be created because anOutOfMemoryError
occurs, then use anOutOfMemoryError
object in place of E in the following step.Acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete this procedure abruptly with reason E or its replacement as determined in the previous step.
A Java Virtual Machine implementation may optimize this procedure by eliding the lock acquisition in step 1 (and release in step 4/5) when it can determine that the initialization of the class has already completed, provided that, in terms of the Java memory model, all happens-before orderings (JLS §17.4.5) that would exist if the lock were acquired, still exist when the optimization is performed.
Chapter 6: The Java Virtual Machine Instruction Set
6.5 Instructions
aconst_init
- Operation
-
Push initial instance of a
value
class - Format
-
aconst_init
indexbyte1
indexbyte2 - Forms
-
aconst_init = 203 (0xcb)
- Operand Stack
-
... →
..., objectref
- Description
-
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1
<<
8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class or interface.The referenced class or interface is resolved (5.4.3.1). The resolved class or interface must be a
value
class that belongs to the same nest as the current class, according to the nestmate test in 5.4.4.The referenced
value
class is initialized if it has not already been initialized (5.5).A
reference
to an instance of thevalue
class, with instance variable values set to the default initial values of their types (2.3, 2.4), is pushed onto the operand stack. Memory for the class instance may be newly allocated from the garbage-collected heap, or may have been allocated previously. - Linking Exceptions
-
During resolution of the symbolic reference to the class or interface, any of the exceptions documented in 5.4.3.1 can be thrown.
If the referenced class or interface is
abstract
or is not avalue
class, aconst_init fails with anIncompatibleClassChangeError
.Otherwise, if the referenced
value
class does not belong to the same nest as the current class, any of the exceptions pertaining to the nestmate test (5.4.4) may be thrown. - Run-time Exception
-
Otherwise, if execution of this aconst_init instruction causes initialization of the referenced class, aconst_init may throw an
Error
as detailed in 5.5. - Notes
-
The aconst_init instruction is similar to the new instruction. But unlike new, the aconst_init instruction does not necessarily allocate a new object on the garbage-collected heap; instead, a previously-created class instance can be used. Also unlike new, the class instance provided by aconst_init is completely initialized—there is no need to invoke an instance initialization method.
The aconst_init instruction may not be used on
value
classes declared outside of the current class's nest. Those classes may declarevalue
class instance creation methods (2.9.4) or other mechanisms to provide classes outside of the nest with a controlled path for instance creation.The withfield instruction is used to create
value
class instances other than the initial instance.
if_acmp<cond>
- Operation
-
Branch if
reference
comparison succeeds - Format
-
if_acmp<cond>
branchbyte1
branchbyte2 - Forms
-
if_acmpeq = 165 (0xa5)
if_acmpne = 166 (0xa6)
- Operand Stack
-
..., value1, value2 →
...
- Description
-
Both value1 and value2 must be of type
reference
. They are both popped from the operand stack and compared. The results of the comparison are as follows:if_acmpeq succeeds if and only if
value1 = 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_icmpeq).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.floatToIntBits
, 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.doubleToLongBits
, 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 standard reference type leading to
another value object may occur to an arbitrary depth (although it must
eventually terminate—circular value objects are impossible to create).
And an attacker with the ability to create arbitrary value
class instances can use if_acmpeq to infer the contents of a
private
field.
monitorenter
- Operation
-
Enter monitor for object
- Format
-
monitorenter
- Forms
-
monitorenter = 194 (0xc2)
- Operand Stack
-
..., objectref →
...
- Description
-
The objectref must be of type
reference
.Each identity object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.
- Run-time Exception
-
If objectref is
null
, monitorenter throws aNullPointerException
.Otherwise, if objectref is a value object, monitorenter throws an
IllegalMonitorStateException
. - Notes
-
A monitorenter instruction may be used with one or more monitorexit instructions (6.5.monitorexit) to implement a
synchronized
statement in the Java programming language (3.14). The monitorenter and monitorexit instructions are not used in the implementation 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, monitorexit throws an
IllegalMonitorStateException
.Otherwise, if 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).
new
- Operation
-
Create new identity object
- Format
-
new
indexbyte1
indexbyte2 - Forms
-
new = 187 (0xbb)
- Operand Stack
-
... →
..., objectref
- Description
-
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1
<<
8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class or interface. The named class or interface is resolved (5.4.3.1) and should result in a non-abstract
identity class or the classObject
. The named class is initialized if it has not already been initialized (5.5).Memory for a new instance of that class is allocated from the garbage-collected heap, and the instance variables of the new object are initialized to the default initial values of their types (2.3, 2.4). The objectref, a
reference
to the instance, is pushed onto the operand stack.On successful resolution of the class, it is initialized if it has not already been initialized (5.5). - Linking Exceptions
-
During resolution of the symbolic reference to the class or interface, any of the exceptions documented in 5.4.3.1 can be thrown.
Otherwise, if the symbolic reference to the class or interface
typeresolves to an interface,oranabstract
class, or avalue
class, new throws anInstantiationError
. - Run-time Exception
-
Otherwise, if execution of this new instruction causes initialization of the referenced class, new may throw an
Error
as detailed in 5.5. - Notes
-
The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method (2.9.1) has been invoked on the uninitialized instance.
withfield
Design discussion: use of the withfield instruction is
restricted to nestmates of the field's declaring class. This prevents
unauthorized creation of value
class instances, including
for classes that declare public
fields.
Alternatively, we could provide a mechanism to express more
permissive withfield access for those classes that do not care
to control instance creation through value
class instance
creation methods or other validation logic. This would require new
accessibility attributes on fields or classes, independent of the "read"
access described by ACC_PUBLIC
, etc.
- Operation
-
Duplicate
value
object with new field value - Format
-
withfield
indexbyte1
indexbyte2 - Forms
-
withfield = 204 (0xcc)
- Operand Stack
-
..., objectref1, value →
..., objectref2
- Description
-
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1
<<
8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a field (5.1), which gives the name and descriptor of the field as well as a symbolic reference to the type in which the field is to be found. The referenced field is resolved (5.4.3.2).The objectref1 must be an instance of a
value
class, and the resolved field must be declared by that class.The type of a value stored by a withfield instruction must be compatible with the descriptor of the referenced field (4.3.2). If the field descriptor type is
boolean
,byte
,char
,short
, orint
, then the value must be anint
. If the field descriptor type isfloat
,long
, ordouble
, then the value must be afloat
,long
, ordouble
, respectively. If the field descriptor type is a reference type, then the value must be of a type that is assignment compatible (JLS §5.2) with the field descriptor type.The resolved field must be declared by a class that belongs to the same nest as the current class, according to the nestmate test in 5.4.4.
The value and objectref1 are popped from the operand stack.
If the value is of type
int
and the field descriptor type isboolean
, then theint
value is narrowed by taking the bitwise AND of value and 1, resulting in value'. Otherwise, the value undergoes value set conversion (2.8.3), resulting in value'.A
reference
to an instance of thevalue
class, objectref2, is pushed onto the operand stack. The referenced field in objectref2 is set to value'. Every other instance field in objectref2 is set to the corresponding field's value in objectref1. Memory for objectref2 may be newly allocated from the garbage-collected heap, or may have been allocated previously. - Linking Exceptions
-
During resolution of the symbolic reference to the field, any of the exceptions pertaining to field resolution (5.4.3.2) can be thrown.
Otherwise, if the resolved field is a
static
field, or the resolved field is not declared by a non-abstract
value
class, withfield throws anIncompatibleClassChangeError
.Otherwise, if the resolved field is not declared by a class that belongs to the same nest as the current class, any of the exceptions pertaining to the nestmate test (5.4.4) may be thrown.
- Run-time Exception
-
Otherwise, if objectref1 is
null
, the withfield instruction throws aNullPointerException
. - Notes
-
The withfield instruction may not be used on
value
classes declared outside of the current class's nest. Those classes may declarevalue
class instance creation methods (2.9.4) or other mechanisms to provide classes outside of the nest with a controlled path for instance creation.