This document describes changes to the Java Virtual Machine Specification, as modified by the Better-defined JVM Class File Validation JEP, JVM Types Cleanup, and Value Objects, to support flattened heap layouts for value objects, a preview feature introduced by JEP 401.
Key changes include:
The
ImplicitCreation
attribute for value classes, with special validation rules (4.7.31, 5.3.5)The
NullRestricted
attribute for field declarations, prompting special field initialization behavior (4.7.32, 5.4.2, 5.5, 6.5.aconst_init, 6.5.new)Null checks on writes to null-restricted fields and arrays (where null-restricted arrays are allocated reflectively) (6.5.aastore, 6.5.putfield, 6.5.putstatic, 6.5.withfield)
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.
Chapter 4: The class
File Format
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 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:
NineEleven attributes are critical to correct interpretation of theclass
file by the Java Virtual Machine:ConstantValue
Code
StackMapTable
BootstrapMethods
Module
ModulePackages
ModuleMainClass
NestHost
NestMembers
ImplicitCreation
NullRestricted
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.20 attributes are not critical to correct interpretation of the
class
file by the Java Virtual Machine, but contain metadata about theclass
file that is either exposed by the class libraries of the Java SE Platform, or made available by tools (in which case the section that specifies an attribute describes it as "optional"):Exceptions
InnerClasses
EnclosingMethod
Synthetic
Signature
Record
SourceFile
SourceDebugExtension
LineNumberTable
LocalVariableTable
LocalVariableTypeTable
Deprecated
RuntimeVisibleAnnotations
RuntimeInvisibleAnnotations
RuntimeVisibleParameterAnnotations
RuntimeInvisibleParameterAnnotations
RuntimeVisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations
AnnotationDefault
MethodParameters
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 |
ImplicitCreation |
4.7.31 | 65.65535 | 21 |
NullRestricted |
4.7.32 | 65.65535 | 21 |
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 |
ImplicitCreation |
65.65535 | 21 | 4.7.31 |
NullRestricted |
65.65535 | 21 | 4.7.32 |
Table 4.7-C. Predefined class
file attributes (by
location)
Attribute | Location | class file |
---|---|---|
SourceFile |
ClassFile |
45.3 |
InnerClasses |
ClassFile |
45.3 |
EnclosingMethod |
ClassFile |
49.0 |
SourceDebugExtension |
ClassFile |
49.0 |
BootstrapMethods |
ClassFile |
51.0 |
Module ,
ModulePackages , ModuleMainClass |
ClassFile |
53.0 |
NestHost ,
NestMembers |
ClassFile |
55.0 |
Record |
ClassFile |
60.0 |
ImplicitCreation |
ClassFile |
65.65535 |
ConstantValue |
field_info |
45.3 |
NullRestricted |
field_info |
65.65535 |
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 |
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.31 The ImplicitCreation
Attribute
The ImplicitCreation
attribute is a fixed-length
attribute in the attributes
table of a
ClassFile
structure in a version 65.65535
class
file. The ImplicitCreation
attribute
authorizes implicit instance creation of a non-abstract
value class beyond normal usage of the aconst_init
and
withfield
instructions.
There must be no more than one ImplicitCreation
attribute in the attributes
table of a
ClassFile
structure representing a
non-abstract
value class. There must not be an
ImplicitCreation
attribute in the attributes
table of any other ClassFile
structure representing a
class, interface, or module.
The ImplicitCreation
attribute must have the following
format:
ImplicitCreation_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 implicit_creation_flags;
}
The items of the ImplicitCreation_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 "ImplicitCreation
". - attribute_length
-
The value of the
attribute_length
item must be two. - implicit_creation_flags
-
The value of the
implicit_creation_flags
item is a mask of flags used to authorize implicit creation of class instances beyond normal usage of theaconst_init
andwithfield
instructions.The flags are specified in Table 4.7.31-A.
Table 4.7.31-A. Implicit creation flags
Flag Name Value Interpretation ACC_DEFAULT
0x0001 Allows use of the initial instance as a default value. ACC_NON_ATOMIC
0x0002 Allows non-atomic updates to create new instances from the field values of existing instances. All bits of the
implicit_creation_flags
item not assigned in Table 4.7.31-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.32 The NullRestricted
Attribute
The NullRestricted
attribute is a fixed-length attribute
in the attributes
table of a field_info
structure in a version 65.65535 class
file. The
NullRestricted
attribute indicates that the field has a
null-restricted type, requiring the field to be initialized to the
initial instance of the field's class () and preventing any attempts to
store null
(6.5.putfield,
6.5.putstatic).
There must be no more than one NullRestricted
attribute
in the attributes
table of a field_info
structure. There must not be a NullRestricted
attribute in
the attributes
table of a field_info
structure
whose descriptor_index
references a primitive type or an
array type.
The descriptor_index
of the field should name a value
class that has an ImplicitCreation
attribute with its
ACC_DEFAULT
flag is set.
The NullRestricted
attribute must have the following
format:
NullRestricted_attribute {
u2 attribute_name_index;
u4 attribute_length;
}
The items of the NullRestricted_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 "NullRestricted
". - attribute_length
-
The value of the
attribute_length
item must be zero.
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
.
If C is a
value
class and has anImplicitCreation
attribute with itsACC_DEFAULT
flag set, then for each non-static
field of C declared with aNullRestricted
attribute, the type is resolved, as if by resolution of an unresolved symbolic reference to a class or interface (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 loading the class or interface named by the field's type depends recursively on loading C itself, loading throws a
ClassCircularityError
.Otherwise, the class or interface named by the field's type must be a
value
class with anImplicitCreation
attribute whoseACC_DEFAULT
flag is set. If not, loading throws anIncompatibleClassChangeError
.
If C is a
value
class that supports implicit initialization of fields and arrays, then the initial instance of C must be well-formed and must not attempt to contain itself. Otherwise, we can't allow C to be successfully loaded, or operations likeArray.newInstance
would have undefined behavior. Additional validation of other null-restricted fields will take place during linking ([5.4]).
- 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.2 Preparation
Preparation involves creating the static fields for a
class or interface and initializing such fields to their default values
(2.3,
2.4).
This does not require the execution of any Java Virtual Machine code;
explicit initializers for static fields are executed as part of
initialization (5.5), not preparation.
Preparation performs linking actions necessary for a class or interface to be able to execute its class or interface initialization method (2.9.2) during initialization (5.5).
To prepare a class or interface C, the Java Virtual Machine imposes constraints on field and method descriptors (4.3), as follows:
For each field of C declared with a
NullRestricted
attribute, the type of the field is resolved, as if by resolution of an unresolved symbolic reference to a class or interface (5.4.3.1).Any exception that can be thrown as a result of failure of class or interface resolution can thus be thrown as a result of failure of preparation.
The resolved type must be of a
value
class with anImplicitCreation
attribute whoseACC_DEFAULT
flag set. If not, preparation fails with anIncompatibleClassChangeError
.
Let L1 be the defining loader of C. For each instance method m declared in C that can override (5.4.5) an instance method declared in a superclass or superinterface
<
D, L2>
, for each class or interface name N mentioned by the descriptor of m (4.3.3), the Java Virtual Machine imposes the loading constraint NL1 = NL2.For each instance method m declared in a superinterface
<
I, L3>
of C, if C does not itself declare an instance method that can override m, then a method is selected (5.4.6) with respect to C and the method m in<
I, L3>
. Let<
D, L2>
be the class or interface that declares the selected method. For each class or interface name N mentioned by the descriptor of m, the Java Virtual Machine imposes the loading constraint NL2 = NL3.
If the class or interface satisfies these constraints, the
Java Virtual Machine creates and initializes its static fields. The
initial value of a field declared with a NullRestricted
attribute is the initial instance of the field's class (6.5.aconst_init). The initial value of
a field of a primitive type is the default value of the type (2.3).
The initial value of any other field is null
.
Preparation may occur at any time following creation but must be completed prior to initialization.
5.5 Initialization
Design discussion: this section specifies the initialization of value classes named by null-restricted reference types in the anewarray and multianewarray instructions, as a prerequesite to creating an initial instance.
We could refine this behavior by:
Skipping initialization for allocations of 0-length arrays. Doing so would tie the initialization logic to dynamic values, which may not be wanted.
Performing initialization whenever a null-restricted reference type is mentioned by an array type, even when no null-restricted array will be allocated (because the number of array type dimensions exceeds the number of dimensions being allocated).
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
.This case includes allocation of a null-restricted value-class-typed array via the
Array.newInstance
method.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.If C is a value class, the initialization of a class that declares a field of type C with a
NullRestricted
attribute.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, for each field of C (in the order of the
fields
array of C), if the field is declared with aNullRestricted
attribute, recursively perform this entire procedure for the class, F, named by the field's type. If necessary, verify and prepare F first.Initialization of F is necessary because the field's initial value is an instance of F.
If the initialization of F 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 F.
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
aastore
- Operation
-
Store into
reference
array - Format
-
aastore
- Forms
-
aastore = 83 (0x53)
- Operand Stack
-
..., arrayref, index, value →
...
- Description
-
The arrayref must be of type
reference
and must refer to an array whose components are of typereference
. The index must be of typeint
, and value must be of typereference
. The arrayref, index, and value are popped from the operand stack.If value is
null
and the component type of the array referenced by arrayref is not null-restricted, then value is stored as the component of the array at index.Otherwise, value is non-If value is a non-null
.null
value of the component type of the array referenced by arrayref, then value is stored as the component of the array at index.Whether value is a value of the array component type is determined according to the rules given for checkcast.
- Run-time Exceptions
-
If arrayref is
null
, aastore throws aNullPointerException
.Otherwise, if index is not within the bounds of the array referenced by arrayref, the aastore instruction throws an
ArrayIndexOutOfBoundsException
.Otherwise, if value is
null
and the component type of the array referenced by arrayref is a null-restricted reference type, aastore throws aNullPointerException
.Otherwise, if the non-
null
value is not a value of the array component type, aastore throws anArrayStoreException
.
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. The initial value of any instance field declared with aNullRestricted
attribute is the initial instance of the field's class. The initial value of any instance field of a primitive type is the default value of the type (2.3). The initial value of any other instance field isnull
. - 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 value object produced by aconst_init may be referred to as the initial instance of the given value class.
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.
anewarray
- Operation
-
Create new array of
reference
- Format
-
anewarray
indexbyte1
indexbyte2 - Forms
-
anewarray = 189 (0xbd)
- Operand Stack
-
..., count →
..., arrayref
- Description
-
The count must be of type
int
. It is popped off the operand stack. The count represents the number of components of the array to be created. 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, interface, or array type.The named class, interface, or array type is resolved (5.4.3.1).
A new array with component type given by the resolved class, interface, or array type, of length count, is allocated from the garbage-collected heap, and a
reference
arrayref to this new array object is pushed onto the operand stack.All components of the new array are initialized to
null
, the default value for.reference
types (2.4) - Linking Exceptions
-
During resolution of the symbolic reference to the class, interface, or array type, any of the exceptions documented in 5.4.3.1 can be thrown.
- Run-time Exceptions
-
Otherwise, if count is less than zero, the anewarray instruction throws a
NegativeArraySizeException
. - Notes
-
The anewarray instruction is used to create a single dimension of an array of object references or part of a multidimensional array.
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 initial value of any instance field declared with theNullRestricted
attribute is the initial instance of the field's class (6.5.aconst_init). The initial value of any instance field of a primitive type is the default value of the type (2.3). The initial value of any other instance field isnull
.The objectref, a
reference
to the instance, is pushed onto the operand stack. - 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 resolves to an interface, an
abstract
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.
putfield
- Operation
-
Set field in object
- Format
-
putfield
indexbyte1
indexbyte2 - Forms
-
putfield = 181 (0xb5)
- Operand Stack
-
..., objectref, value →
...
- 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 class, interface, or array type in which the field is to be found. The referenced field is resolved (5.4.3.2).The type of a value stored by a putfield 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 a value of the field descriptor type. If the field isfinal
, it must be declared in the current class, and the instruction must occur in an instance initialization method of the current class (2.9.1).The value and objectref are popped from the operand stack.
The objectref must be of type
reference
but not an array type.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'.The referenced field in objectref is set to value'.
- 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, putfield throws anIncompatibleClassChangeError
.Otherwise, if the resolved field is
final
, it must be declared in the current class, and the instruction must occur in an instance initialization method of the current class. Otherwise, anIllegalAccessError
is thrown. - Run-time Exception
-
Otherwise, if objectref is
null
, or if the value to store isnull
and the resolved field is declared with aNullRestricted
attribute, the putfield instruction throws aNullPointerException
.
putstatic
- Operation
-
Set static field in class
- Format
-
putstatic
indexbyte1
indexbyte2 - Forms
-
putstatic = 179 (0xb3)
- Operand Stack
-
..., value →
...
- 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 class, interface, orarrayreference type in which the field is to be found. The referenced field is resolved (5.4.3.2).On successful resolution of the field, the class or interface that declared the resolved field is initialized if that class or interface has not already been initialized (5.5).
The type of a value stored by a putstatic 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 a value of the field descriptor type. If the field isfinal
, it must be declared in the current class or interface, and the instruction must occur in the class or interface initialization method of the current class or interface (2.9.2).The value is 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'.The referenced field in the class or interface is set to value'.
- Linking Exceptions
-
During resolution of the symbolic reference to the class or interface field, any of the exceptions pertaining to field resolution (5.4.3.2) can be thrown.
Otherwise, if the resolved field is not a
static
(class) field or an interface field, putstatic throws anIncompatibleClassChangeError
.Otherwise, if the resolved field is
final
, it must be declared in the current class or interface, and the instruction must occur in the class or interface initialization method of the current class or interface. Otherwise, anIllegalAccessError
is thrown. - Run-time Exception
-
Otherwise, if execution of this putstatic instruction causes initialization of the referenced class or interface, putstatic may throw an
Error
as detailed in 5.5.Otherwise, if the value to store is
null
and the resolved field is declared with aNullRestricted
attribute, the putstatic instruction throws aNullPointerException
. - Notes
-
A putstatic instruction may be used only to set the value of an interface field on the initialization of that field. Interface fields may be assigned to only once, on execution of an interface variable initialization expression when the interface is initialized (5.5, JLS §9.3.1).
withfield
- 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
, or if the value to store isnull
and the resolved field is declared with aNullRestricted
attribute, 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.