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 primitive objects, a preview feature introduced by JEP 401.
Key changes include:
Primitive class declarations, with special validation rules (4.1, 4.5, 4.6, 5.4.2)
Additional metadata for reference-favoring and validation-enforcing primitive classes (4.1, 4.7.31)
Metadata for abstract classes to declare their support for primitive subclasses (4.1, 5.3.5)
Special factory methods to provide a standard way for classes and interfaces to support instance creation without traditional constructors (2.9.4, 4.6, 4.9.1)
Implicit implementation of the
PrimitiveObject
andIdentityObject
interfaces, and detection of conflicts (5.3.5)Support for inlinable reference types in descriptors, signatures, and verification (2.4, 4.3.2, 4.7.9.1, 4.10.1.2, 5.4.2, 5.5)
Additional support for inlinable reference types in class constants, array components, and dynamic type checks (4.4.1, 5.4.3.1, 5.5, 6.5.aastore, 6.5.anewarray, 6.5.checkcast, 6.5.ldc, 6.5.multianewarray)
New
defaultvalue
andwithfield
opcodes, to support creation of primitive objects (4.9.1, 4.10.1.9.defaultvalue, 4.10.1.9.withfield, 6.5.defaultvalue, 6.5.withfield)Custom behavior for
if_acmpeq
,if_acmpne
,monitorenter
, andmonitorexit
when applied to primitive objects (6.5.if_acmp_cond, 6.5.monitorenter, 6.5.monitorexit)Rejecting use of
new
with a primitive class, and special treatment ofnew java/lang/Object
(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.
Chapter 2: The Structure of the Java Virtual Machine
2.2 Data Types
The Java Virtual Machine operates on two kinds of types: basic primitive types and reference types. There are, correspondingly, two kinds of values that can be stored in variables, passed as arguments, returned by methods, and operated upon: basic primitive values and reference values.
The Java Virtual Machine expects that nearly all type checking is done prior to run time, typically by a compiler, and does not have to be done by the Java Virtual Machine itself. Values of basic primitive types need not be tagged or otherwise be inspectable to determine their types at run time, or to be distinguished from values of reference types. Instead, the instruction set of the Java Virtual Machine distinguishes its operand types using instructions intended to operate on values of specific types. For instance, iadd, ladd, fadd, and dadd are all Java Virtual Machine instructions that add two numeric values and produce numeric results, but each is specialized for its operand type: int
, long
, float
, and double
, respectively. For a summary of type support in the Java Virtual Machine instruction set, see 2.11.1.
The Java Virtual Machine contains explicit support for objects. An object is either a dynamically allocated class instance or an array. A reference to an object is considered to have Java Virtual Machine type reference
. References are polymorphic: a single reference
may also be a value of multiple class types, interface types, or array reference types. Values of type reference
can be thought of as pointers to objects. More than one reference to an object may exist. Objects are always operated on, passed, and tested via values of type reference
.
2.3 Basic Primitive Types and Values
The basic primitive data types supported by the Java Virtual Machine are the numeric types, the boolean
type (2.3.4), and the returnAddress
type (2.3.3).
The numeric types consist of the integral types (2.3.1) and the floating-point types (2.3.2).
The integral types are:
byte
, whose values are 8-bit signed two's-complement integers, and whose default value is zeroshort
, whose values are 16-bit signed two's-complement integers, and whose default value is zeroint
, whose values are 32-bit signed two's-complement integers, and whose default value is zerolong
, whose values are 64-bit signed two's-complement integers, and whose default value is zerochar
, whose values are 16-bit unsigned integers representing Unicode code points in the Basic Multilingual Plane, encoded with UTF-16, and whose default value is the null code point ('\u0000'
)
The floating-point types are:
float
, whose values are elements of the float value set or, where supported, the float-extended-exponent value set, and whose default value is positive zerodouble
, whose values are elements of the double value set or, where supported, the double-extended-exponent value set, and whose default value is positive zero
The values of the boolean
type encode the truth values true
and false
, and the default value is false
.
The First Edition of The Java® Virtual Machine Specification did not consider
boolean
to be a Java Virtual Machine type. However,boolean
values do have limited support in the Java Virtual Machine. The Second Edition of The Java® Virtual Machine Specification clarified the issue by treatingboolean
as a type.
The values of the returnAddress
type are pointers to the opcodes of Java Virtual Machine instructions. Of the primitive types, only the returnAddress
type is not directly associated with a Java programming language type.
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, have a unique identity dynamically assigned to them when they are created. An identity object may be an instance of an identity class or an array. These objects can mutate their instance fields or components and are associated with a synchronization monitor.
Other objects, called primitive objects, have no identity. A primitive object is always an instance of a primitive class. These objects have immutable instance fields and cannot be used for synchronization. A Java Virtual Machine implementation can sometimes inline a primitive object, avoiding the memory and indirection overhead usually associated with references.
A reference value typically belongs to multiple reference types, which may be any 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.An inlinable reference type names a primitive class defined in a
class
file. The type's values are references to instances of the named primitive class. Thenull
reference is not a value of any inlinable reference type.
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 basic 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 standard or inlinable 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.
A reference
value may also be the special null reference, a reference to no object, which will be denoted here by null
. The null
reference initially has no run-time type, but may be cast to any type. The default value of a reference
type is null
.
The default value of a standard reference type or an array type is null
. The default value of an inlinable reference type is the default instance of the named class: an instance whose fields all have the default value for their type.
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 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 primitive 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 Unnamed Factory Methods
Design discussion: this section introduces a new kind of special method, an unnamed factory method, with its own special name, <new>
. It follows the pattern of 2.9.1 and 2.9.2.
Unnamed factory methods are designed for use by primitive classes, allowing them to provide 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 primitive class instantiation is the only intended Java language use for now, unnamed factory methods could also be used to support instance creation in interfaces and abstract classes, and perhaps as part of a modified protocol for identity class instantiation.
Alternative approaches:
Instead of
<new>
, an unnamed factory method could be identified with the name<init>
and a non-void
return type. This would complicate some usages of the name<init>
(see, for example, 4.10.1.9.invokespecial), but might simplify recognition of these methods by some tools.Rather than allowing a particular special name for a specific purpose, we could open up the entire
<...>
namespace for arbitrary usage. The name<new>
would then be a compiler convention, not a special feature recognized by the JVM.A new invocation opcode, invokenew, could be introduced for the purpose of unnamed factory method invocation. (The new opcode is unsuitable, because it has no
Methodref
.) The opcode might also support<init>
methods, implicitly performing the new-dup-invokespecial sequence (although the<init>
descriptor would not accurately reflect the actual return type).
A class or interface may declare zero or more unnamed factory methods. These methods return instances of the class or interface while encapsulating the process used to create or look up those instances.
An unnamed factory method is declared with the special name <new>
.
The declaration and use of an unnamed factory 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, an unnamed factory method may be invoked only by the invokestatic instruction (4.9.1).
Because the name
<new>
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, defaultvalue, 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
Design discussion: this section introduces an ACC_PRIM_SUPER
flag to indicate an abstract class that permits primitive instances.
Other possible encodings:
A
PrimitiveInstantiable
attribute (to use a strawman name)Re-interpreting the combination of
ACC_PRIMITIVE
andACC_ABSTRACT
(ACC_PRIMITIVE
here means "may have primitive instances")
This section also introduces an ACC_ATOMIC
flag to indicate a primtive class whose instances must be handled atomically. (The term "atomic" may be misleading, and we may prefer a different name.)
Other possible encodings:
A
NonTearable
orAtomicPrimitive
attribute (again, strawman name)A similarly-named marker interface, where a class implements the interface to request the behavior
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_ATOMIC
0x0040 Updates to inlined instances must be atomic. ACC_PRIMITIVE
0x0100 Is a primitive class. ACC_INTERFACE
0x0200 Is an interface, not a class. ACC_ABSTRACT
0x0400 Declared abstract
; must not be instantiated.ACC_PRIM_SUPER
0x0800 May be extended by a primitive class. 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_PRIMITIVE
,ACC_PRIM_SUPER
,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
flagandACC_PRIM_SUPER
flags must not be set.In a
class
file with version number 61.65535, theACC_PRIMITIVE
flag indicates that this class is a primitive class. In aclass
file with any other version number, the 0x0100 bit is ignored, and theACC_PRIMITIVE
flag is considered not to be set. If theACC_PRIMITIVE
flag is set, theACC_FINAL
flag must also be set, and theACC_ABSTRACT
,ACC_PRIM_SUPER
,ACC_ENUM
,ACC_INTERFACE
, andACC_MODULE
flags must not be set.The value
0x0100
has never been used by classes or fields, but is interpreted asACC_NATIVE
when applied to a method.In a
class
file with version number 61.65535, theACC_ATOMIC
flag may be applied to a primitive class to require that instances be handled atomically when inlined in a variable or array. In aclass
file with any other version number, the 0x0040 bit is ignored, and theACC_ATOMIC
flag is considered not to be set. If theACC_ATOMIC
flag is set, theACC_PRIMITIVE
flag must also be set.The value
0x0040
is interpreted as (the closely-related)ACC_VOLATILE
when applied to a field, and asACC_BRIDGE
when applied to a method.In a
class
file with version number 61.65535, theACC_PRIM_SUPER
flag indicates that this abstract class may be extended by a primitive class. Primitive instances will be created without executing any instance initialization method of this class (2.9.1). In aclass
file with any other version number, the 0x0800 bit is ignored, and theACC_PRIM_SUPER
flag is considered not to be set. If theACC_PRIM_SUPER
flag is set, theACC_ABSTRACT
flag must also be set.The value
0x0800
has never been used by classes or fields, but is interpreted asACC_STRICT
when applied to a method.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. TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.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. TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.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. EachCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.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 <new>
(2.9), they must not contain the ASCII characters <
or >
(that is, left angle bracket or right angle bracket).
4.3 Descriptors
4.3.2 Field Descriptors
A field descriptor represents the type of a field, parameter, value, or local variable.
- FieldDescriptor:
- FieldType
- FieldType:
BaseTypeClassTypeArrayType- BasicPrimitiveType
- ReferenceType
BaseType:BasicPrimitiveType:- (one of)
B
C
D
F
I
J
S
Z
- ReferenceType:
- StandardReferenceType
- InlinableReferenceType
- ArrayType
ClassType:StandardReferenceType:L
ClassName;
- InlinableReferenceType:
Q
ClassName;
- ArrayType:
[
ComponentType- ComponentType:
- FieldType
ClassName represents a binary class or interface name encoded in internal form (4.2.1).
A field descriptor mentions a class or interface name if the name appears as a ClassName in the descriptor. This includes a ClassName nested in the ComponentType of an ArrayType.
The interpretation of field descriptors as types is shown in Table 4.3-A. See 2.2, 2.3, and 2.4 for the meaning of these types.
A field descriptor representing an array type is valid only if it represents a type with 255 or fewer dimensions.
Table 4.3-A. Interpretation of field descriptors
FieldType term | Type |
---|---|
B |
byte |
C |
char |
D |
double |
F |
float |
I |
int |
J |
long |
L ClassName ; |
|
Q ClassName ; |
Inlinable reference type of the named primitive class |
S |
short |
Z |
boolean |
[ |
Array of given component type |
The field descriptor of an instance variable of type
int
is simplyI
.The field descriptor of an instance variable of type
Object
isLjava/lang/Object;
. Note that the internal form of the binary name for classObject
is used.The field descriptor of an instance variable of the multidimensional array type
double[][][]
is[[[D
.
4.4 The Constant Pool
4.4.1 The CONSTANT_Class_info
Structure
Design discussion: this section generalizes the contents of a CONSTANT_Class
to allow the full domain of reference type descriptors (currently comprising L
, Q
, and [
descriptors).
Downstream, there are essentially two kinds of CONSTANT_Class
usages:
Where a class or interface is needed, and descriptors (including array types) are illegal
Where a type is needed, and class or interface names are implicit standard reference types
This change addresses the second use case, allowing an arbitrary reference type in anewarray
, ldc
, checkcast
, instanceof
, and bootstrap arguments.
Alternative approaches:
Make no changes to
CONSTANT_Class
, and pursue a different handling of types whereCONSTANT_Class
is used. As a minimum, this means finding a way to support inlinable reference array creation. This might look like an API, or a new kind of constant pool entry.Keep
Q
descriptors inCONSTANT_Class
, but prohibitL
descriptors. A plain class name must be implicitly interpreted as a standard reference type already, so support forL
descriptors is redundant. On the other hand, a simple rule that any reference type descriptor can appear in aCONSTANT_Class
is potentially helpful for both JVMs and code generators, providing more uniform treatment of types and eliminating some extra complexity.(In any case, extending this feature to basic primitive type descriptors is impossible, because
I
,D
, etc., are already valid class names.)
The CONSTANT_Class_info
structure is used to represent a class, an interface, or an array a reference type:
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
The items of the CONSTANT_Class_info
structure are as follows:
- tag
The
tag
item has the valueCONSTANT_Class
(7).- 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) consisting of one of:a valid binary class or interface name encoded in internal form (4.2.1), or
an array typea reference type, encoded as a validArrayTypeReferenceType descriptor (4.3.2).
In a
class
file with a version number other than 61.65535, thename_index
item must not be a ReferenceType descriptor of the form StandardReferenceType or InlinableReferenceType.In some contexts, a
CONSTANT_Class_info
structure is expected to name a class or interface, and a ReferenceType descriptor is explicitly disallowed. In other contexts, aCONSTANT_Class_info
structure is expected to represent a type; in this case, a ReferenceType descriptor is allowed, and a class or interface name is interpreted as a the standard reference type of the given class or interface.
For example, the
name_index
string representing the classString
isjava/lang/String
. Thename_index
string representing the identity class typeString
isLjava/lang/String;
. Thename_index
string representing the interfaceRunnable
isjava/lang/Runnable
. Thename_index
string representing the inlinable primitive class typeFoo
isQFoo;
. Thename_index
string representing the array typeThread[]
is[Ljava/lang/Thread;
. Thename_index
string representing the array typeint[][]
is[[I
.
Note that it is not supported to represent a basic primitive type with a
CONSTANT_Class_info
. For example, thename_index
stringD
represents a class or interface namedD
, not the basic primitive typedouble
.
4.4.2 The CONSTANT_Fieldref_info
, CONSTANT_Methodref_info
, and CONSTANT_InterfaceMethodref_info
Structures
References to fields, methods, and interface methods are represented by similar structures:
CONSTANT_Fieldref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
CONSTANT_InterfaceMethodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
The items of these structures are as follows:
- tag
The
tag
item of aCONSTANT_Fieldref_info
structure has the valueCONSTANT_Fieldref
(9).The
tag
item of aCONSTANT_Methodref_info
structure has the valueCONSTANT_Methodref
(10).The
tag
item of aCONSTANT_InterfaceMethodref_info
structure has the valueCONSTANT_InterfaceMethodref
(11).- class_index
The value of the
class_index
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).The
class_index
item represents aclass, interface, or arrayreference type that has the field or method as a member.In a
CONSTANT_Methodref_info
structure, theclass_index
item should name a class type or an array type, not an interface type.In a
CONSTANT_InterfaceMethodref_info
structure, theclass_index
item should name an interface type, not a class type or an array type.- 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 the name and descriptor of the field or method.In a
CONSTANT_Fieldref_info
structure, the indicated descriptor must be a field descriptor (4.3.2). Otherwise, the indicated descriptor must be a method descriptor (4.3.3).In a
CONSTANT_Methodref_info
or aCONSTANT_InterfaceMethoref_info
structure, the indicated name must be a valid method name (4.2.2) and must not be<clinit>
. The indicated descriptor must be a method descriptor (4.3.3). If the name is<init>
, the return type of the method descriptor must beV
.Class initialization methods, which have the name
<clinit>
(2.9.2), cannot be referenced directly. They may only be invoked implicitly by the Java Virtual Machine (5.5).
4.4.6 The CONSTANT_NameAndType_info
Structure
The CONSTANT_NameAndType_info
structure is used to represent a field or method, without indicating which class or interface it belongs to:
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
The items of the CONSTANT_NameAndType_info
structure are as follows:
- tag
The
tag
item has the valueCONSTANT_NameAndType
(12).- 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 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) representing a valid field descriptor or method descriptor (4.3.2, 4.3.3).In a
class
file with a version number other than 61.65535, the field or method descriptor must not make use of any type of the form InlinableReferenceType.
4.4.8 The CONSTANT_MethodHandle_info
Structure
Design discussion: the withfield and defaultvalue 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<new>
.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.9 The CONSTANT_MethodType_info
Structure
The CONSTANT_MethodType_info
structure is used to represent a method type:
CONSTANT_MethodType_info {
u1 tag;
u2 descriptor_index;
}
The items of the CONSTANT_MethodType_info
structure are as follows:
- tag
The
tag
item has the valueCONSTANT_MethodType
(16).- 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) representing a valid method descriptor (4.3.3).In a
class
file with a version number other than 61.65535, the method descriptor must not make use of any type of the form InlinableReferenceType.
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<new>
. The indicated descriptor must be a method descriptor (4.3.3).We could allow
<new>
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 a primitive class, each field must have at least one of its
ACC_STATIC
orACC_FINAL
flags set. In an abstract class that has itsACC_PRIM_SUPER
flag set, each field must have itsACC_STATIC
flag 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).In a
class
file with a version number other than 61.65535, the field descriptor must not make use of any type of the form InlinableReferenceType.- 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
Design discussion: this section requires that unnamed factory methods (named <new>
) are static
and have a return type that matches their declaring class or interface. By restricting the descriptor in this way, clients can rely on a predictable, useful return type.
Alternatively, we could allow a subtype or supertype as the return type, or impose no constraints at all. One potential use case is a hidden class, which is incapable of naming its class type in a descriptor.
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.Methods of classes with names other than
<init>
and<clinit>
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 primitive class, and in an abstract class that has its
ACC_PRIM_SUPER
flag set, 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.A method of a class or interface named
<new>
(2.9.4) must have itsACC_STATIC
flag 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 primitive class or an interface must not have the name
<init>
.- 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
<new>
, then the descriptor must denote a return type that is a type of the current class or interface. For a primitive class, the return type must be an inlinable reference type.
In a
class
file with a version number other than 61.65535, the method descriptor must not make use of any type of the form InlinableReferenceType.A future edition of this specification may require that the last parameter descriptor of the method descriptor is an array type if the
ACC_VARARGS
flag is set in theaccess_flags
item.- attributes_count
The value of the
attributes_count
item indicates the number of additional attributes of this method.- attributes[]
Each value of the
attributes
table must be anattribute_info
structure (4.7).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
JavaFlags
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 |
JavaFlags |
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 |
JavaFlags |
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 |
JavaFlags |
ClassFile , field_info , method_info , record_component_info |
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.3 The Code
Attribute
The Code
attribute is a variable-length attribute in the attributes
table of a method_info
structure (4.6). A Code
attribute contains the Java Virtual Machine instructions and auxiliary information for a method, including an instance initialization method and a class or interface initialization method (2.9.1, 2.9.2).
If the method is either native
or abstract
, its method_info
structure must not have a Code
attribute in its attributes
table. Otherwise, its method_info
structure must have exactly one Code
attribute in its attributes
table.
The Code
attribute must have the following format:
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
The items of the Code_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 "Code
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes.- max_stack
The value of the
max_stack
item gives the maximum depth of the operand stack of this method (2.6.2) at any point during execution of the method.- max_locals
The value of the
max_locals
item gives the number of local variables in the local variable array allocated upon invocation of this method (2.6.1), including the local variables used to pass parameters to the method on its invocation.The greatest local variable index for a value of type
long
ordouble
ismax_locals - 2
. The greatest local variable index for a value of any other type ismax_locals - 1
.- code_length
The value of the
code_length
item gives the number of bytes in thecode
array for this method.The value of
code_length
must be greater than zero (as thecode
array must not be empty) and less than 65536.- code[]
The
code
array gives the actual bytes of Java Virtual Machine code that implement the method.When the
code
array is read into memory on a byte-addressable machine, if the first byte of the array is aligned on a 4-byte boundary, the tableswitch and lookupswitch 32-bit offsets will be 4-byte aligned. (Refer to the descriptions of those instructions for more information on the consequences ofcode
array alignment.)The contents of the
code
array are subject to extensive constraints during verification ([5.4.1]), as described in 4.9.- exception_table_length
The value of the
exception_table_length
item gives the number of entries in theexception_table
array.- exception_table[]
Each entry in the
exception_table
array describes one exception handler in thecode
array. The order of the handlers in theexception_table
array is significant (2.10).The contents of the
exception_table
array are validated during verification, along with thecode
array.Each
exception_table
entry contains the following four items:- start_pc, end_pc
The values of the two items
start_pc
andend_pc
indicate the ranges in thecode
array at which the exception handler is active. The value ofstart_pc
should be a valid index into thecode
array of the opcode of an instruction. The value ofend_pc
either should be a valid index into thecode
array of the opcode of an instruction or should be equal tocode_length
, the length of thecode
array. The value ofstart_pc
should be less than the value ofend_pc
.The
start_pc
is inclusive andend_pc
is exclusive; that is, the exception handler will be active while the program counter is within the interval [start_pc
,end_pc
).The fact that
end_pc
is exclusive is a historical mistake in the design of the Java Virtual Machine: if the Java Virtual Machine code for a method is exactly 65535 bytes long and ends with an instruction that is 1 byte long, then that instruction cannot be protected by an exception handler. A compiler writer can work around this bug by limiting the maximum size of the generated Java Virtual Machine code for any method, instance initialization method, or static initializer (the size of any code array) to 65534 bytes.- handler_pc
The value of the
handler_pc
item indicates the start of the exception handler. The value of the item should be a valid index into thecode
array and should be the index of the opcode of an instruction.- catch_type
If the value of the
catch_type
item is nonzero, it 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 of exceptions that this exception handler is designated to catch. The exception handler will be called only if the thrown exception is an instance of the given class or one of its subclasses.The
CONSTANT_Class_info
structure, if present, should not reference a ReferenceType descriptor.The verifier checks that the class is
Throwable
or a subclass ofThrowable
(4.9.2).If the value of the
catch_type
item is zero, this exception handler is called for all exceptions.This is used to implement
finally
(3.13).
- attributes_count
The value of the
attributes_count
item indicates the number of attributes of theCode
attribute.- 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 aCode
attribute are listed in Table 4.7-C.The rules concerning attributes defined to appear in the
attributes
table of aCode
attribute are given in 4.7.The rules concerning nonstandard attributes in the
attributes
table of aCode
attribute are given in 4.7.1.
4.7.4 The StackMapTable
Attribute
...
A verification type specifies the type of either one or two locations, where a location is either a single local variable or a single operand stack entry. A verification type is represented by a discriminated union, verification_type_info
, that consists of a one-byte tag, indicating which item of the union is in use, followed by zero or more bytes, giving more information about the tag.
union verification_type_info {
Top_variable_info;
Integer_variable_info;
Float_variable_info;
Long_variable_info;
Double_variable_info;
Null_variable_info;
UninitializedThis_variable_info;
Object_variable_info;
Uninitialized_variable_info;
}
A verification type that specifies one location in the local variable array or in the operand stack is represented by the following items of the verification_type_info
union:
The
Top_variable_info
item indicates that the local variable has the verification typetop
.Top_variable_info { u1 tag = ITEM_Top; /* 0 */ }
The
Integer_variable_info
item indicates that the location has the verification typeint
.Integer_variable_info { u1 tag = ITEM_Integer; /* 1 */ }
The
Float_variable_info
item indicates that the location has the verification typefloat
.Float_variable_info { u1 tag = ITEM_Float; /* 2 */ }
The
Null_variable_info
type indicates that the location has the verification typenull
.Null_variable_info { u1 tag = ITEM_Null; /* 5 */ }
The
UninitializedThis_variable_info
item indicates that the location has the verification typeuninitializedThis
.UninitializedThis_variable_info { u1 tag = ITEM_UninitializedThis; /* 6 */ }
The
Object_variable_info
item indicates that the location has the verification type which is theclass, interface, or arraytype represented by theCONSTANT_Class_info
structure (4.4.1) found in theconstant_pool
table at the index given bycpool_index
.A
CONSTANT_Class_info
structure that names a class or interface is interpreted in this context as the standard reference type of the named class or interface.Object_variable_info { u1 tag = ITEM_Object; /* 7 */ u2 cpool_index; }
The
Uninitialized_variable_info
item indicates that the location has the verification typeuninitialized(Offset)
. TheOffset
item indicates the offset, in thecode
array of theCode
attribute that contains thisStackMapTable
attribute, of the new instruction (6.5.new) that created the object being stored in the location.Uninitialized_variable_info { u1 tag = ITEM_Uninitialized; /* 8 */ u2 offset; }
A verification type that specifies two locations in the local variable array or in the operand stack is represented by the following items of the verification_type_info
union:
The
Long_variable_info
item indicates that the first of two locations has the verification typelong
.Long_variable_info { u1 tag = ITEM_Long; /* 4 */ }
The
Double_variable_info
item indicates that the first of two locations has the verification typedouble
.Double_variable_info { u1 tag = ITEM_Double; /* 3 */ }
The
Long_variable_info
andDouble_variable_info
items indicate the verification type of the second of two locations as follows:If the first of the two locations is a local variable, then:
It should not be the local variable with the highest index.
The next higher numbered local variable has the verification type
top
.
If the first of the two locations is an operand stack entry, then:
It should not be the topmost location of the operand stack.
The next location closer to the top of the operand stack has the verification type
top
.
...
4.7.5 The Exceptions
Attribute
The Exceptions
attribute is a variable-length attribute in the attributes
table of a method_info
structure (4.6). The Exceptions
attribute indicates which checked exceptions a method may throw.
There must be no more than one Exceptions
attribute in the attributes
table of a method_info
structure.
The Exceptions
attribute should have the following format:
Exceptions_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_exceptions;
u2 exception_index_table[number_of_exceptions];
}
The items of the Exceptions_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 "Exceptions
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes.- number_of_exceptions
The value of the
number_of_exceptions
item should indicate the number of entries in theexception_index_table
.- exception_index_table[]
Each value in the
exception_index_table
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 that this method is declared to throw. TheCONSTANT_Class_info
structure should not reference a ReferenceType descriptor.
A method should throw an exception only if at least one of the following three criteria is met:
The exception is an instance of
RuntimeException
or one of its subclasses.The exception is an instance of
Error
or one of its subclasses.The exception is an instance of one of the exception classes specified in the
exception_index_table
just described, or one of their subclasses.
These requirements are not enforced in the Java Virtual Machine; they are enforced only at compile time.
4.7.6 The InnerClasses
Attribute
The InnerClasses
attribute is a variable-length attribute in the attributes
table of a ClassFile
structure (4.1).
There must be no more than one InnerClasses
attribute in the attributes
table of a ClassFile
structure.
The InnerClasses
attribute should have the following format:
InnerClasses_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_classes;
{ u2 inner_class_info_index;
u2 outer_class_info_index;
u2 inner_name_index;
u2 inner_class_access_flags;
} classes[number_of_classes];
}
The items of the InnerClasses_attribute
structure are as follows:
- attribute_name_index
The value of the
attribute_name_index
item is an index into theconstant_pool
table. Theconstant_pool
entry at that index is aCONSTANT_Utf8_info
structure (4.4.7) representing the string "InnerClasses
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes.- number_of_classes
The value of the
number_of_classes
item should indicate the number of entries in theclasses
array.- classes[]
Every
CONSTANT_Class_info
entry (4.4.1) in theconstant_pool
table whichrepresentsnames a class or interface C that is not a package member should have exactly one corresponding entry in theclasses
array.If a class or interface has members that are classes or interfaces, its
constant_pool
table (and hence itsInnerClasses
attribute) should refer to each such member (JLS §13.1), even if that member is not otherwise mentioned by the class.In addition, the
constant_pool
table of every nested class and nested interface should refer to its enclosing class, so altogether, every nested class and nested interface will haveInnerClasses
information for each enclosing class and for each of its own nested classes and interfaces.Each entry in the
classes
array should contain the following four items:- inner_class_info_index
The value of the
inner_class_info_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_Class_info
structure representing C. TheCONSTANT_Class_info
structure should not reference a ReferenceType descriptor.- outer_class_info_index
If C is not a member of a class or an interface - that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5) - then the value of the
outer_class_info_index
item should be zero.Otherwise, the value of the
outer_class_info_index
item should be a valid index into theconstant_pool
table, and the entry at that index should be aCONSTANT_Class_info
structure representing the class or interface of which C is a member. TheCONSTANT_Class_info
structure, if present, should not reference a ReferenceType descriptor. The value of theouter_class_info_index
item should not equal the the value of theinner_class_info_index
item.- inner_name_index
If C is anonymous (JLS §15.9.5), the value of the
inner_name_index
item must be zero.Otherwise, the value of the
inner_name_index
item should be a valid index into theconstant_pool
table, and the entry at that index should be aCONSTANT_Utf8_info
structure that represents the original simple name of C, as given in the source code from which thisclass
file was compiled.- inner_class_access_flags
The value of the
inner_class_access_flags
item is a mask of flags used to denote access permissions to and properties of class or interface C as declared in the source code from which thisclass
file was compiled. It is used by a compiler to recover the original information when source code is not available. The flags are specified in Table 4.7.6-A.Table 4.7.6-A. Nested class access and property flags
Flag Name Value Interpretation ACC_PUBLIC
0x0001 Marked or implicitly public
in source.ACC_PRIVATE
0x0002 Marked private
in source.ACC_PROTECTED
0x0004 Marked protected
in source.ACC_STATIC
0x0008 Marked or implicitly static
in source.ACC_FINAL
0x0010 Marked or implicitly final
in source.ACC_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 type. ACC_ENUM
0x4000 Declared as an enum
type.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.
The Java Virtual Machine does not check the consistency of an
InnerClasses
attribute against aclass
file representing a class or interface referenced by the attribute.
4.7.7 The EnclosingMethod
Attribute
The EnclosingMethod
attribute is a fixed-length attribute in the attributes
table of a ClassFile
structure (4.1) in a version 49.0 or later class
file. A class or interface should have an EnclosingMethod
attribute if and only if it represents a local class or an anonymous class (JLS §14.3, JLS §15.9.5).
There must be no more than one EnclosingMethod
attribute in the attributes
table of a ClassFile
structure representing a class or interface. There must not be an EnclosingMethod
attribute in the attributes
table of a ClassFile
structure representing a module.
The EnclosingMethod
attribute should have the following format:
EnclosingMethod_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 class_index;
u2 method_index;
}
The items of the EnclosingMethod_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 "EnclosingMethod
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes, and should be four.- class_index
The value of the
class_index
item 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 the innermost class or interface that encloses the declaration of the current class. TheCONSTANT_Class_info
structure should not reference a ReferenceType descriptor.- method_index
If the current class is not immediately enclosed by a method or constructor, then the value of the
method_index
item should be zero.In particular,
method_index
should be zero if the current class was immediately enclosed in source code by an instance initializer, static initializer, instance variable initializer, or class variable initializer. (The first two concern both local classes and anonymous classes, while the last two concern anonymous classes declared on the right hand side of a field assignment.)Otherwise, the value of the
method_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_NameAndType_info
structure (4.4.6) representing the name and type of a method in the class or interface referenced by theclass_index
attribute above.It is the responsibility of a Java compiler to ensure that the method identified via the
method_index
is indeed the closest lexically enclosing method of the class that contains thisEnclosingMethod
attribute.
4.7.9 The Signature
Attribute
4.7.9.1 Signatures
Some of the terminology in this section may be refined as the related JLS changes are developed.
Signatures encode declarations written in the Java programming language that use types outside the type system of the Java Virtual Machine. They support reflection and debugging, as well as compilation when only class
files are available.
A Java compiler should emit a signature for any class, interface, constructor, method, field, or record component whose declaration uses type variables or parameterized types. Specifically, a Java compiler should emit:
A class signature for any class or interface declaration which is either generic, or has a parameterized type as a superclass or superinterface, or both.
A method signature for any method or constructor declaration which is either generic, or has a type variable or parameterized type as the return type or a formal parameter type, or has a type variable in a
throws
clause, or any combination thereof.If the
throws
clause of a method or constructor declaration does not involve type variables, then a compiler may treat the declaration as having nothrows
clause for the purpose of emitting a method signature.A field signature for any field, formal parameter, local variable, or record component declaration whose type uses a type variable or a parameterized type.
Signatures are specified using a grammar which follows the notation of [4.3.1]. In addition to that notation:
The syntax [x] on the right-hand side of a production denotes zero or one occurrences of x. That is, x is an optional symbol. The alternative which contains the optional symbol actually defines two alternatives: one that omits the optional symbol and one that includes it.
A very long right-hand side may be continued on a second line by clearly indenting the second line.
The grammar includes the terminal symbol Identifier to denote the name of a type, field, method, formal parameter, local variable, or type variable, as generated by a Java compiler. Such a name should not contain any of the ASCII characters .
;
[
/
<
>
:
(that is, the characters forbidden in method names (4.2.2) and also colon) but may contain characters that do not appear in an identifier in the Java programming language (JLS §3.8).
Signatures rely on a hierarchy of nonterminals known as type signatures:
A Java type signature represents either a reference type or a primitive type of the Java programming language.
- JavaTypeSignature:
- ReferenceTypeSignature
BaseTypeValueTypeSignature
The following production from 4.3.2 is repeated here for convenience:
- BaseType:
- (one of)
B
C
D
F
I
J
S
Z
A reference type signature represents a reference type of the Java programming language, that is, a reference class or interface type, a type variable, or an array type.
A reference class type signature represents a (possibly parameterized) reference class or interface type. A reference class type signature should be formulated such that it can be reliably mapped to the binary name of the class it denotes by erasing any type arguments and converting each
.
character to a$
character.A type variable signature represents a type variable.
An array type signature represents one dimension of an array type.
- ReferenceTypeSignature:
ClassTypeSignatureReferenceClassTypeSignature- TypeVariableSignature
- ArrayTypeSignature
ClassTypeSignature:ReferenceClassTypeSignature:L
[PackageSpecifier]
SimpleClassTypeSignature {ClassTypeSignatureSuffix};
- PackageSpecifier:
- Identifier
/
{PackageSpecifier} - SimpleClassTypeSignature:
- Identifier [TypeArguments]
- TypeArguments:
<
TypeArgument {TypeArgument}>
- TypeArgument:
- [WildcardIndicator] ReferenceTypeSignature
*
- WildcardIndicator:
+
-
- ClassTypeSignatureSuffix:
.
SimpleClassTypeSignature- TypeVariableSignature:
T
Identifier;
- ArrayTypeSignature:
[
JavaTypeSignature
A value type signature represents a primitive value type of the Java programming language, that is, a primitive class value type or a basic primitive type.
A value class type signature represents a (possibly parameterized) primitive value class type. It has the same format as a reference class type signature, except that it begins with a
Q
prefix.- ValueTypeSignature:
- ValueClassTypeSignature
- BasicPrimitiveType
- ValueClassTypeSignature:
Q
[PackageSpecifier]
SimpleClassTypeSignature {ClassTypeSignatureSuffix};
The following production from 4.3.2 is repeated here for convenience:
- BasicPrimitiveType:
- (one of)
B
C
D
F
I
J
S
Z
A class signature encodes type information about a (possibly generic) class or interface declaration. It describes any type parameters of the class or interface, and lists its (possibly parameterized) direct superclass and direct superinterfaces, if any. A type parameter is described by its name, followed by any class bound and interface bounds.
- ClassSignature:
- [TypeParameters] SuperclassSignature {SuperinterfaceSignature}
- TypeParameters:
<
TypeParameter {TypeParameter}>
- TypeParameter:
- Identifier ClassBound {InterfaceBound}
- ClassBound:
:
[ReferenceTypeSignature]- InterfaceBound:
:
ReferenceTypeSignature- SuperclassSignature:
- ClassTypeSignature
- SuperinterfaceSignature:
- ClassTypeSignature
A method signature encodes type information about a (possibly generic) method declaration. It describes any type parameters of the method; the (possibly parameterized) types of any formal parameters; the (possibly parameterized) return type, if any; and the types of any exceptions declared in the method's throws
clause.
- MethodSignature:
- [TypeParameters]
(
{JavaTypeSignature})
Result {ThrowsSignature} - Result:
- JavaTypeSignature
- VoidDescriptor
- ThrowsSignature:
^
ClassTypeSignature^
TypeVariableSignature
The following production from 4.3.3 is repeated here for convenience:
- VoidDescriptor:
V
A method signature encoded by the
Signature
attribute might not correspond exactly to the method descriptor in themethod_info
structure (4.3.3). In particular, there is no assurance that the number of formal parameter types in the method signature is the same as the number of parameter descriptors in the method descriptor. The numbers are the same for most methods, but certain constructors in the Java programming language have an implicitly declared parameter which a compiler represents with a parameter descriptor but may omit from the method signature. See the note in 4.7.18 for a similar situation involving parameter annotations.
A field signature encodes the (possibly parameterized) type of a field, formal parameter, local variable, or record component declaration.
- FieldSignature:
- ReferenceTypeSignature
4.7.16 The RuntimeVisibleAnnotations
Attribute
4.7.16.1 The element_value
structure
The element_value
structure is a discriminated union representing the value of an element-value pair. It has the following format:
element_value {
u1 tag;
union {
u2 const_value_index;
{ u2 type_name_index;
u2 const_name_index;
} enum_const_value;
u2 class_info_index;
annotation annotation_value;
{ u2 num_values;
element_value values[num_values];
} array_value;
} value;
}
The tag
item uses a single ASCII character to indicate the type of the value of the element-value pair. This determines which item of the value
union is in use. [Table 4.7.16.1-A] shows the valid characters for the tag
item, the type indicated by each character, and the item used in the value
union for each character. The table's fourth column is used in the description below of one item of the value
union.
Table 4.7.16.1-A. Interpretation of tag
values as types
tag Item |
Type | value Item |
Constant Type |
---|---|---|---|
B |
byte |
const_value_index |
CONSTANT_Integer |
C |
char |
const_value_index |
CONSTANT_Integer |
D |
double |
const_value_index |
CONSTANT_Double |
F |
float |
const_value_index |
CONSTANT_Float |
I |
int |
const_value_index |
CONSTANT_Integer |
J |
long |
const_value_index |
CONSTANT_Long |
S |
short |
const_value_index |
CONSTANT_Integer |
Z |
boolean |
const_value_index |
CONSTANT_Integer |
s |
String |
const_value_index |
CONSTANT_Utf8 |
e |
Enum class | enum_const_value |
Not applicable |
c |
Class |
class_info_index |
Not applicable |
@ |
Annotation interface | annotation_value |
Not applicable |
[ |
Array type | array_value |
Not applicable |
The value item represents the value of an element-value pair. The item is a union, whose own items are as follows:
- const_value_index
The
const_value_index
item denotes a constant of either a primitive type or the typeString
as the value of this element-value pair.The value of the
const_value_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be of a type appropriate to thetag
item, as specified in the fourth column of [Table 4.7.16.1-A].- enum_const_value
The
enum_const_value
item denotes an enum constant as the value of this element-value pair.The
enum_const_value
item consists of the following two items:- type_name_index
The value of the
type_name_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_Utf8_info
structure (4.4.7) representing a field descriptor (4.3.2). Theconstant_pool
entry gives the internal form of the binary name of the type of the enum constant represented by thiselement_value
structure (4.2.1).- const_name_index
The value of the
const_name_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_Utf8_info
structure (4.4.7). Theconstant_pool
entry gives the simple name of the enum constant represented by thiselement_value
structure.
- class_info_index
The
class_info_index
item denotes a class literal as the value of this element-value pair.The
class_info_index
item should be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index should be aCONSTANT_Utf8_info
structure (4.4.7) representing a return descriptor (4.3.3). The return descriptor gives the type corresponding to the class literal represented by thiselement_value
structure. Types correspond to class literals as follows:For a class literal C
.class
, where C is the name of a class or interface, the corresponding type is C. The return descriptor in theconstant_pool
should be aClassTypeStandardReferenceType.For a class literal representing an inlinable reference type, the return descriptor in the
constant_pool
should be an InlinableReferenceType.For a class literal T[]
.class
, where T[] is an array type, the corresponding type is T[]. The return descriptor in theconstant_pool
should be an ArrayType.For a class literal p
.class
, where p is the name of a primitive type, the corresponding type is p. The return descriptor in theconstant_pool
should be a BasicPrimitiveType character.For a class literal
void.class
, the corresponding type isvoid
. The return descriptor in theconstant_pool
should be V.
For example, the class literal
Object.class
corresponds to the typeObject
, so theconstant_pool
entry isLjava/lang/Object;
, whereas the class literalint.class
corresponds to the typeint
, so theconstant_pool
entry isI
.The class literal
void.class
corresponds tovoid
, so theconstant_pool
entry is V, whereas the class literalVoid.class
corresponds to the typeVoid
, so theconstant_pool
entry isLjava/lang/Void;
.- annotation_value
The
annotation_value
item denotes a "nested" annotation as the value of this element-value pair.The value of the
annotation_value
item should be anannotation
structure (4.7.16) that gives the annotation represented by thiselement_value
structure.- array_value
The
array_value
item denotes an array as the value of this element-value pair.The
array_value
item should consist of the following two items:- num_values
The value of the
num_values
item should give the number of elements in the array represented by thiselement_value
structure.- values[]
Each value in the
values
table should give the corresponding element of the array represented by thiselement_value
structure.
4.7.25 The Module
Attribute
The Module
attribute is a variable-length attribute in the attributes
table of a ClassFile
structure (4.1) in a version 53.0 or later class
file. The Module
attribute indicates the modules required by a module; the packages exported and opened by a module; and the services used and provided by a module.
There must be exactly one Module
attribute in the attributes
table of a ClassFile
structure representing a module. There must not be a Module
attribute in the attributes
table of a ClassFile
structure representing a class or interface.
The Module
attribute must have the following format:
Module_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 module_name_index;
u2 module_flags;
u2 module_version_index;
u2 requires_count;
{ u2 requires_index;
u2 requires_flags;
u2 requires_version_index;
} requires[requires_count];
u2 exports_count;
{ u2 exports_index;
u2 exports_flags;
u2 exports_to_count;
u2 exports_to_index[exports_to_count];
} exports[exports_count];
u2 opens_count;
{ u2 opens_index;
u2 opens_flags;
u2 opens_to_count;
u2 opens_to_index[opens_to_count];
} opens[opens_count];
u2 uses_count;
u2 uses_index[uses_count];
u2 provides_count;
{ u2 provides_index;
u2 provides_with_count;
u2 provides_with_index[provides_with_count];
} provides[provides_count];
}
The items of the Module_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 "Module
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes.- module_name_index
The value of the
module_name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Module_info
structure (4.4.11).The
module_name_index
item denotes the current module.- module_flags
The value of the
module_flags
item is a mask of flags, where the flags that are set are interpreted as follows:- 0x0020 (
ACC_OPEN
) Indicates that this module is open.
- 0x1000 (
ACC_SYNTHETIC
) Indicates that this module was not explicitly or implicitly declared.
- 0x8000 (
ACC_MANDATED
) Indicates that this module was implicitly declared.
- 0x0020 (
- module_version_index
The value of the
module_version_index
item must be either zero or a valid index into theconstant_pool
table. If the value of the item is zero, then no version information about the current module is present. If the value of the item is nonzero, then theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure.The
module_version_index
item represents the version of the current module.- requires_count
The value of the
requires_count
item indicates the number of entries in therequires
table.If the current module is
java.base
, thenrequires_count
must be zero.If the current module is not
java.base
, thenrequires_count
must be at least one.- requires[]
Each entry in the
requires
table specifies a dependence of the current module. The items in each entry are as follows:- requires_index
The value of the
requires_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Module_info
structure.The
requires_index
item denotes a module on which the current module depends.At most one entry in the
requires
table may specify a module of a given name with itsrequires_index
item.- requires_flags
The value of the
requires_flags
item is a mask of flags, where the flags that are set are interpreted as follows:- 0x0020 (
ACC_TRANSITIVE
) Indicates that any module which depends on the current module implicitly declares a dependence on the module indicated by this entry.
- 0x0040 (
ACC_STATIC_PHASE
) Indicates that this dependence is mandatory in the static phase, i.e., at compile time, but is optional in the dynamic phase, i.e., at run time.
- 0x1000 (
ACC_SYNTHETIC
) Indicates that this dependence was not explicitly or implicitly declared in the source of the module declaration.
- 0x8000 (
ACC_MANDATED
) Indicates that this dependence was implicitly declared in the source of the module declaration.
If the current module is not
java.base
, and theclass
file version number is 54.0 or above, then neitherACC_TRANSITIVE
norACC_STATIC_PHASE
may be set inrequires_flags
.- 0x0020 (
- requires_version_index
The value of the
requires_version_index
item must be either zero or a valid index into theconstant_pool
table. If the value of the item is zero, then no version information about the dependence is present. If the value of the item is nonzero, then theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure.The
requires_version_index
item represents the version of the module specified byrequires_index
.
Unless the current module is
java.base
, exactly one entry in therequires
table must have both arequires_index
item which indicatesjava.base
and arequires_flags
item which has theACC_SYNTHETIC
flag not set.- exports_count
The value of the
exports_count
item indicates the number of entries in theexports
table.- exports[]
Each entry in the
exports
table specifies a package exported by the current module, such thatpublic
andprotected
types in the package, and theirpublic
andprotected
members, may be accessed from outside the current module, possibly from a limited set of "friend" modules.The items in each entry are as follows:
- exports_index
The value of the
exports_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Package_info
structure (4.4.12).The
exports_index
item represents a package exported by the current module.At most one entry in the
exports
table may specify a package of a given name with itsexports_index
item.- exports_flags
The value of the
exports_flags
item is a mask of flags, where the flags that are set are interpreted as follows:- 0x1000 (
ACC_SYNTHETIC
) Indicates that this export was not explicitly or implicitly declared in the source of the module declaration.
- 0x8000 (
ACC_MANDATED
) Indicates that this export was implicitly declared in the source of the module declaration.
- 0x1000 (
- exports_to_count
The value of the
exports_to_count
indicates the number of entries in theexports_to_index
table.If
exports_to_count
is zero, then this package is exported by the current module in an unqualified fashion; code in any other module may access the types and members in the package.If
exports_to_count
is nonzero, then this package is exported by the current module in a qualified fashion; only code in the modules listed in theexports_to_index
table may access the types and members in the package.- exports_to_index[]
The value of each entry in the
exports_to_index
table must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Module_info
structure.Each entry denotes a module whose code can access the types and members in this exported package.
For each entry in the
exports
table, at most one entry in itsexports_to_index
table may specify a module of a given name.
- opens_count
The value of the
opens_count
item indicates the number of entries in theopens
table.opens_count
must be zero if the current module is open.- opens[]
Each entry in the
opens
table specifies a package opened by the current module, such that all types in the package, and all their members, may be accessed from outside the current module via the reflection libraries of the Java SE Platform, possibly from a limited set of "friend" modules.The items in each entry are as follows:
- opens_index
The value of the
opens_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Package_info
structure.The
opens_index
item represents a package opened by the current module.At most one entry in the
opens
table may specify a package of a given name with itsopens_index
item.- opens_flags
The value of the
opens_flags
item is a mask of flags, where the flags that are set are interpreted as follows:- 0x1000 (
ACC_SYNTHETIC
) Indicates that this opening was not explicitly or implicitly declared in the source of the module declaration.
- 0x8000 (
ACC_MANDATED
) Indicates that this opening was implicitly declared in the source of the module declaration.
- 0x1000 (
- opens_to_count
The value of the
opens_to_count
indicates the number of entries in theopens_to_index
table.If
opens_to_count
is zero, then this package is opened by the current module in an unqualified fashion; code in any other module may reflectively access the types and members in the package.If
opens_to_count
is nonzero, then this package is opened by the current module in a qualified fashion; only code in the modules listed in theexports_to_index
table may reflectively access the types and members in the package.- opens_to_index[]
The value of each entry in the
opens_to_index
table must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Module_info
structure.Each entry denotes a module whose code can access the types and members in this opened package.
For each entry in the
opens
table, at most one entry in itsopens_to_index
table may specify a module of a given name.
- uses_count
The value of the
uses_count
item indicates the number of entries in theuses_index
table.- uses_index[]
The value of each entry in the
uses_index
table must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure (4.4.1). EachCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.Each entry represents a service interface which the current module may discover via
java.util.ServiceLoader
.At most one entry in the
uses_index
table may specify a service interface of a given name.- provides_count
The value of the
provides_count
item indicates the number of entries in theprovides
table.- provides[]
Each entry in the
provides
table represents a service implementation for a given service interface.The items in each entry are as follows:
- provides_index
The value of the
provides_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure. TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.The
provides_index
item represents a service interface for which the current module provides a service implementation.At most one entry in the
provides
table may specify a service interface of a given name with itsprovides_index
item.- provides_with_count
The value of the
provides_with_count
indicates the number of entries in theprovides_with_index
table.provides_with_count
must be nonzero.- provides_with_index[]
The value of each entry in the
provides_with_index
table must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure. EachCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.Each entry represents a service implementation for the service interface specified by
provides_index
.For each entry in the
provides
table, at most one entry in itsprovides_with_index
table may specify a service implementation of a given name.
4.7.27 The ModuleMainClass
Attribute
The ModuleMainClass
attribute is a fixed-length attribute in the attributes
table of a ClassFile
structure (4.1) in a version 53.0 or later class
file. The ModuleMainClass
attribute indicates the main class of a module.
There must be no more than one ModuleMainClass
attribute in the attributes
table of a ClassFile
structure representing a module. There must not be a ModuleMainClass
attribute in the attributes
table of a ClassFile
structure representing a class or interface.
The ModuleMainClass
attribute must have the following format:
ModuleMainClass_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 main_class_index;
}
The items of the ModuleMainClass_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 "ModuleMainClass
".- attribute_length
The value of the
attribute_length
item must be two.- main_class_index
The value of the
main_class_index
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). TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.The
main_class_index
item represents the main class of the current module.
4.7.28 The NestHost
Attribute
The NestHost
attribute is a fixed-length attribute in the attributes
table of a ClassFile
structure in a version 55.0 or later class
file. The NestHost
attribute records the nest host of the nest to which the current class or interface claims to belong (5.4.4).
There must be no more than one NestHost
attribute in the attributes
table of a ClassFile
structure representing a class or interface. There must not be a NestHost
attribute in the attributes
table of a ClassFile
structure representing a module.
The NestHost
attribute must have the following format:
NestHost_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 host_class_index;
}
The items of the NestHost_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 "NestHost
".- attribute_length
The value of the
attribute_length
item must be two.- host_class_index
The value of the
host_class_index
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). TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.The
host_class_index
item represents a class or interface which is the nest host for the current class or interface.If the nest host cannot be loaded, or is not in the same run-time package as the current class or interface, or does not authorize nest membership for the current class or interface, then an error may occur during access control (5.4.4).
4.7.29 The NestMembers
Attribute
The NestMembers
attribute is a variable-length attribute in the attributes
table of a ClassFile
structure (4.1) in a version 55.0 or later class
file. The NestMembers
attribute records the classes and interfaces that are authorized to claim membership in the nest hosted by the current class or interface (5.4.4).
There must be no more than one NestMembers
attribute in the attributes
table of a ClassFile
structure representing a class or interface. There must not be a NestMembers
attribute in the attributes
table of a ClassFile
structure representing a module.
The attributes
table of a ClassFile
structure must not contain both a NestMembers
attribute and a NestHost
attribute.
This rule prevents a nest host from claiming membership in a different nest. It is implicitly a member of the nest that it hosts.
The NestMembers
attribute must have the following format:
NestMembers_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_classes;
u2 classes[number_of_classes];
}
The items of the NestMembers_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 "NestMembers
".- 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 must indicate the number of entries in theclasses
array.- classes[]
Each entry in the
classes
array must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure (4.4.1). EachCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.Each entry represents a class or interface which is a member of the nest hosted by the current class or interface.
The
classes
array is consulted by access control (5.4.4). It should consist of references to other classes and interfaces that are in the same run-time package and haveNestHost
attributes which reference the current class or interface. Array items that do not meet these criteria are ignored by access control.
4.7.31 The JavaFlags
Attribute
Design discussion: this new attribute provides a place for a Java compiler to store metadata about primitive classes (and, in the future, other constructs), where that information is useful for compilation but ignored by the JVM.
The name of the attribute reflects the intent that these are flags used by the Java programming language, not the JVM. Other possible names are JavaLanguageFlags
or JavaExtendedFlags
.
Alternatively, we could define a more focused attribute (PrimitiveClassProperties
), or handle each flag with its own attribute (ReferenceDefaultPrimitiveClass
, etc.) Since primitive classes are final
, we could also encode these flags with marker interfaces.
The particular flag values, along with the precise number of flags that are reserved, are subject to change, depending on the preferences of javac
.
The JavaFlags
attribute is a fixed-length attribute in the attributes
table of a ClassFile
, field_info
, method_info
, or record_component_info
structure (4.1, 4.5, 4.6, 4.7.30) in a version 61.65535 class
file. A JavaFlags
attribute is used by a compiler for the Java programming language to store simple supplementary information about a class, interface, module, constructor, method, field, or record component.
There must be no more than one JavaFlags
attribute in the attributes
table of a ClassFile
, field_info
, method_info
, or record_component_info
structure.
The JavaFlags
attribute should have the following format:
JavaFlags_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 extended_flags;
}
The items of the JavaFlags_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 "JavaFlags
".- attribute_length
The value of the
attribute_length
item indicates the length of the attribute, excluding the initial six bytes, and should be two.- extended_flags
The value of the
extended_flags
item is a mask of flags, where the flags that are set are interpreted as follows:- 0x0001 (
ACC_REF_DEFAULT
) When applied to a
ClassFile
structure, indicates that a primitive class has a name that should be interpreted as its reference type rather than its value type. TheACC_PRIMITIVE
flag of theClassFile
structure should also be set.- 0x0002 (
ACC_VALIDATED
) When applied to a
ClassFile
structure, indicates that a primitive class has requested support from the language to reject class instances created outside of the class's constructors. TheACC_PRIMITIVE
flag of theClassFile
structure should also be set.
All flags that are unspecified for the kind of structure to which the attribute is applied should be set to 0.
- 0x0001 (
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 defaultvalue opcode nor the withfield opecode 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<new>
.Only the invokespecial instruction is allowed to invoke an instance initialization method (2.9.1). Only the invokestatic instruction is allowed to invoke an unnamed factory 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, defaultvalue, 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
.Every defaultvalue instruction must reference a constant pool entry of kind
CONSTANT_Class
that represents an inlinable reference type.No new instruction may reference a constant pool entry of kindEvery new 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. TheCONSTANT_Class_info
structure must not reference a ReferenceType descriptor.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 bethea 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 primitive 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 bethea 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.1 Accessors for Java Virtual Machine Artifacts
The Prolog term Class
represents a binary class or interface that has been successfully loaded (5.3). This specification does not mandate the precise structure of this term.
Similarly, the Prolog term Method
represents a method of a Class
, and the Prolog term Loader
represents a class loader of a Class
. We do not specify the structure of the method or class loader.
We stipulate the existence of 18 Prolog predicates ("accessors") that have certain expected behavior but whose formal definitions are not given in this specification.
- classClassName(Class, ClassName)
Extracts the name,
ClassName
, of the classClass
.- classIsInterface(Class)
True iff the class,
Class
, is an interface.- classIsPrimitive(Class)
True iff the class,
Class
, is a primitive class.- classSuperClassName(Class, SuperClassName)
Extracts the name,
SuperClassName
, of the superclass of classClass
.- classInterfaceNames(Class, InterfaceNames)
Extracts a list,
InterfaceNames
, of the names of the direct superinterfaces of the classClass
.- classDefiningLoader(Class, Loader)
Extracts the defining class loader,
Loader
, of the classClass
.- isBootstrapLoader(Loader)
True iff the class loader
Loader
is the bootstrap class loader.- loadedClass(Name, InitiatingLoader, ClassDefinition)
True iff there exists a class named
Name
whose representation (in accordance with this specification) when loaded by the class loaderInitiatingLoader
isClassDefinition
.- methodName(Method, Name)
Extracts the name,
Name
, of the methodMethod
.- methodAccessFlags(Method, AccessFlags)
Extracts the access flags,
AccessFlags
, of the methodMethod
.- methodDescriptor(Method, Descriptor)
Extracts the descriptor,
Descriptor
, of the methodMethod
.- isInit(Method)
True iff
Method
(regardless of class) is<init>
.- isNotInit(Method)
True iff
Method
(regardless of class) is not<init>
.- isProtected(MemberClass, MemberName, MemberDescriptor)
True iff there is a member named
MemberName
with descriptorMemberDescriptor
in the classMemberClass
and it isprotected
.- isNotProtected(MemberClass, MemberName, MemberDescriptor)
True iff there is a member named
MemberName
with descriptorMemberDescriptor
in the classMemberClass
and it is notprotected
.- parseFieldDescriptor(Descriptor, Type)
Converts a field descriptor,
Descriptor
, into the corresponding verification typeType
(4.10.1.2).The verification type derived from descriptor types
byte
,short
,boolean
, andchar
isint
.- parseMethodDescriptor(Descriptor, ArgTypeList, ReturnType)
Converts a method descriptor,
Descriptor
, into a list of verification types,ArgTypeList
, corresponding to the method argument types, and a verification type,ReturnType
, corresponding to the return type.The verification type derived from descriptor types
byte
,short
,boolean
, andchar
isint
. A void return is represented with the special symbolvoid
.- parseCodeAttribute(Class, Method, FrameSize, MaxStack, ParsedCode, Handlers, StackMap)
Extracts the instruction stream,
ParsedCode
, of the methodMethod
inClass
, as well as the maximum operand stack size,MaxStack
, the maximal number of local variables,FrameSize
, the exception handlers,Handlers
, and the stack mapStackMap
.The representation of the instruction stream and stack map attribute must be as specified in 4.10.1.3 and 4.10.1.4.
If a
StackMapTable
attribute is absent, the implicit stack map attribute is used (4.7.4).If an entry in the stack map table violates structural constraints (4.9.2) because of an invalid
Code
array offset, an invalid stack type array size, or an invalid local variable type array size, theparseCodeAttribute
predicate fails.- samePackageName(Class1, Class2)
True iff the package names of
Class1
andClass2
are the same.
The above accessors are used to define loadedSuperclasses
, which produces a list of a class's superclasses.
loadedSuperclasses(Class, [ Superclass | Rest ]) :-
classSuperClassName(Class, SuperclassName),
classDefiningLoader(Class, L),
loadedClass(SuperclassName, L, Superclass),
loadedSuperclasses(Superclass, Rest).
loadedSuperclasses(Class, []) :-
classClassName(Class, 'java/lang/Object').
When type checking a method's body, it is convenient to access information about the method. For this purpose, we define an environment, a six-tuple consisting of:
- a class
- a method
- the declared return type of the method (or
void
) - the instructions in a method
- the maximal size of the operand stack
- a list of exception handlers
We specify accessors to extract information from the environment.
allInstructions(Environment, Instructions) :-
Environment = environment(_Class, _Method, _ReturnType,
Instructions, _, _).
exceptionHandlers(Environment, Handlers) :-
Environment = environment(_Class, _Method, _ReturnType,
_Instructions, _, Handlers).
maxOperandStackLength(Environment, MaxStack) :-
Environment = environment(_Class, _Method, _ReturnType,
_Instructions, MaxStack, _Handlers).
currentClassLoader(Environment, Loader) :-
Environment = environment(Class, _Method, _ReturnType,
_Instructions, _, _),
classDefiningLoader(Class, L).
thisClass(Environment, Class) :-
Environment = environment(Class, _Method, _ReturnType,
_Instructions, _, _).
thisType(Environment, class(ClassName, L)) :-
Environment = environment(Class, _Method, _ReturnType,
_Instructions, _, _),
classDefiningLoader(Class, L),
classClassName(Class, ClassName).
thisMethodReturnType(Environment, ReturnType) :-
Environment = environment(_Class, _Method, ReturnType,
_Instructions, _, _).
offsetStackFrame(Environment, Offset, StackFrame) :-
allInstructions(Environment, Instructions),
member(stackMap(Offset, StackFrame), Instructions).
Finally, we specify a general predicate used throughout the type rules:
notMember(_, []).
notMember(X, [A | More]) :- X \= A, notMember(X, More).
The principle guiding the determination as to which accessors are stipulated and which are fully specified is that we do not want to over-specify the representation of the
class
file. Providing specific accessors to theClass
orMethod
term would force us to completely specify the format for a Prolog term representing theclass
file.
4.10.1.2 Verification Type System
The type checker enforces a type system based upon a hierarchy of verification types, illustrated below.
Verification type hierarchy:
top
____________/\____________
/ \
/ \
oneWord twoWord
/ | \ / \
/ | \ / \
int float reference long double
/ \
/ \_____________
/ \
/ \
uninitialized +------------------+
/ \ | reference type |
/ \ | hierarchy |
uninitializedThis uninitialized(Offset) +------------------+
uninitialized +-------------------+
/ \ | reference types |
/ \ | and null |
uninitializedThis uninitialized(Offset) +-------------------+
|
|
null
The type null
is no longer a subtype of all reference types, and identifying exactly which reference types it is related to is beyond the scope of this diagram.
Most verification types have a direct correspondence with the primitive and reference types described in 2.2 and represented by field descriptors in Table 4.3-A:
The primitive types
double
,float
,int
, andlong
(field descriptorsD
,F
,I
,J
) each correspond to the verification type of the same name.Class and interfaceStandard reference types (field descriptors beginningL
) correspond to verification types that use the functorclass
. The verification typeclass(N, L)
represents the standard reference type of the class or interface whose binary name isN
as loaded by the loaderL
. Note thatL
is an initiating loader (5.3) of the class represented byclass(N, L)
and may, or may not, be the class's defining loader.For example, the
classstandard reference typeObject
would be represented asclass('java/lang/Object', L)
, where the defining loader of class'java/lang/Object'
, as loaded byL
, is the bootstrap loader.Inlinable reference types (field descriptors beginning
Q
) correspond to verification types that use the functorinlinable
. The verification typeinlinable(N, L)
represents the inlinable reference type of the primitive class whose binary name isN
as loaded by the loaderL
.For example, the inlinable reference type of a primitive class
Point
would be represented asinlinable('Point', L)
, for an appropriateL
.Array types (field descriptors beginning
[
) correspond to verification types that use the functorarrayOf
. Note that the primitive typesbyte
,char
,short
, andboolean
do not correspond to verification types, but an array type whose element type isbyte
,char
,short
, orboolean
does correspond to a verification type; such verification types support the baload, bastore, caload, castore, saload, sastore, and newarray instructions.The verification type
arrayOf(T)
represents the array type whose component type is the verification typeT
.The verification type
arrayOf(byte)
represents the array type whose component type isbyte
.The verification type
arrayOf(char)
represents the array type whose component type ischar
.The verification type
arrayOf(short)
represents the array type whose component type isshort
.The verification type
arrayOf(boolean)
represents the array type whose component type isboolean
.
For example, the array types
int[]
andObject[]
would be represented by the verification typesarrayOf(int)
andarrayOf(class('java/lang/Object', BL))
respectively. The array typesbyte[]
andboolean[][]
would be represented by the verification typesarrayOf(byte)
andarrayOf(arrayOf(boolean))
respectively.
The remaining verification types are described as follows:
The verification types
top
,oneWord
,twoWord
, andreference
describe abstract unions of other types, as illustrated above, and are represented in Prolog as atoms.The verification types
uninitialized
,uninitializedThis
, anduninitialized(Offset)
describe references to objects created withnew
that have not yet been initialized (2.9.2).uninitialized
anduninitializedThis
are represented with an atom.uninitialized(Offset)
is represented by applying the functoruninitialized
to an argument representing the numerical value of theOffset
.The verification type
null
describes the result of theaconst_null
instruction, and is represented in Prolog as an atom.
The subtyping rules for verification types are as follows.
Subtyping is reflexive.
isAssignable(X, X).
The type top
is a supertype of all other types.
isAssignable(oneWord, top).
isAssignable(twoWord, top).
A type is a subtype of some other type, X, if its direct supertype is a subtype of X.
isAssignable(int, X) :- isAssignable(oneWord, X).
isAssignable(float, X) :- isAssignable(oneWord, X).
isAssignable(long, X) :- isAssignable(twoWord, X).
isAssignable(double, X) :- isAssignable(twoWord, X).
isAssignable(reference, X) :- isAssignable(oneWord, X).
isAssignable(class(_, _), X) :- isAssignable(reference, X).
isAssignable(inlinable(_,_), X) :- isAssignable(reference, X).
isAssignable(arrayOf(_), X) :- isAssignable(reference, X).
isAssignable(null, X) :- isAssignable(reference, X).
isAssignable(uninitialized, X) :- isAssignable(reference, X).
isAssignable(uninitializedThis, X) :- isAssignable(uninitialized, X).
isAssignable(uninitialized(_), X) :- isAssignable(uninitialized, X).
The type null
is a subtype of all standard and array reference types.
isAssignable(null, class(_, _)).
isAssignable(null, arrayOf(_)).
These subtype rules are not necessarily the most obvious formulation of subtyping. There is a clear split between subtyping rules among reference types, and rules for the remaining verification types. The split allows us to state general subtyping relations between reference types and other verification types. These relations hold independently of a reference type's position in the type hierarchy, and help to prevent excessive class loading by a Java Virtual Machine implementation. For example, we do not want to start climbing the superclass hierarchy in response to a query of the form
class(foo, L) <: twoWord
.
We also have a rule that says subtyping is reflexive, so together these rules cover most verification types that are not reference types.
Subtype rules for the reference types are specified recursively with isWideningReference
.
isAssignable(From, To) :- isWideningReference(From, To).
The verifier allows any reference type to be widened to an interface type.
isWideningReference(class(_, _), class(To, L)) :-
loadedClass(To, L, ToClass),
classIsInterface(ToClass).
isWideningReference(arrayOf(_), class(To, L)) :-
loadedClass(To, L, ToClass),
classIsInterface(ToClass).
isWideningReference(inlinable(_,_), class(To, L)) :-
loadedClass(To, L, ToClass),
classIsInterface(ToClass).
This approach is less strict than the Java Programming Language, which will not allow an assignment to an interface unless the value is statically known to implement or extend the interface. The Java Virtual Machine instead uses a run-time check to ensure that invocations of interface methods actually operate on objects that implement the interface (6.5.invokeinterface). But there is no requirement that a reference stored by a variable of an interface type refers to an object that actually implements that interface.
A class standard reference type can be widened to another class standard reference type if that type refers to the loaded class or one of its superclasses.
isWideningReference(class(ClassName, L1), class(ClassName, L2)) :-
L1 \= L2,
loadedClass(ClassName, L1, Class),
loadedClass(ClassName, L2, Class).
isWideningReference(class(From, L1), class(To, L2)) :-
From \= To,
loadedClass(From, L1, FromClass),
loadedSuperclases(FromClass, Supers),
member(Super, Supers),
classClassName(Super, ToClass),
loadedClass(To, L2, ToClass).
An inlinable reference type can be widened to the standard reference type for that class.
isWideningReference(inlinable(N, L), class(N, L)).
isWideningReference(inlinable(From, L1), class(To, L2)) :-
isWideningReference(class(From, L1), class(To, L2)).
Array types are subtypes of Object
.
isWideningReference(arrayOf(_), class('java/lang/Object', _)).
Subtyping between arrays of reference type is covariant.
isWideningReference(arrayOf(X), arrayOf(Y)) :-
isWideningReference(X, Y).
4.10.1.3 Instruction Representation
Individual bytecode instructions are represented in Prolog as terms whose functor is the name of the instruction and whose arguments are its parsed operands.
For example, an aload instruction is represented as the term
aload(N)
, which includes the indexN
that is the operand of the instruction.
The instructions as a whole are represented as a list of terms of the form:
instruction(Offset, AnInstruction)
For example,
instruction(21, aload(1))
.
The order of instructions in this list must be the same as in the class
file.
Some instructions have operands that refer to entries in the constant_pool
table. Such entries are represented as functor applications of the form:
class(N, L)
,inlinable(N, L)
, orarrayOf(T)
for a constant pool entry that is aCONSTANT_Class_info
structure (4.4.1).These are verification types, as described in 4.10.1.2.
If the
name_index
item of the structure gives the name of a class or interface,N
is that name, andL
is the class loader of the class or interface containing the constant pool. The name is interpreted in this context as the standard reference type of the referenced class or interface.If the
name_index
item of the structure gives an inlinable type,N
is the given class or interface name, andL
is the class loader of the class or interface containing the constant pool.If the
name_index
item of the structure gives an array type,T
is the array component type.field(FieldClassType, FieldName, FieldDescriptor)
for a constant pool entry that is aCONSTANT_Fieldref_info
structure (4.4.2).FieldClassType
is the verification type of the class, interface, or array type referenced by theclass_index
item in the structure.FieldName
andFieldDescriptor
correspond to the name and field descriptor referenced by thename_and_type_index
item of the structure.method(MethodClassType, MethodName, MethodDescriptor)
for a constant pool entry that is aCONSTANT_Methodref_info
structure (4.4.2).MethodClassType
is the verification type of the class, interface, or array type referenced by theclass_index
item of the structure.MethodName
andMethodDescriptor
correspond to the name and method descriptor referenced by thename_and_type_index
item of the structure.imethod(MethodClassType, MethodName, MethodDescriptor)
for a constant pool entry that is aCONSTANT_InterfaceMethodref_info
structure (4.4.2).MethodClassType
is the verification type of the class, interface, or array type referenced by theclass_index
item of the structure.MethodName
andMethodDescriptor
correspond to the name and method descriptor referenced by thename_and_type_index
item of the structure.string(Value)
for a constant pool entry that is aCONSTANT_String_info
structure (4.4.3).Value
is the string referenced by thestring_index
item of the structure.int(Value)
for a constant pool entry that is aCONSTANT_Integer_info
structure (4.4.4).Value
is theint
constant represented by thebytes
item of the structure.float(Value)
for a constant pool entry that is aCONSTANT_Float_info
structure (4.4.4).Value
is thefloat
constant represented by thebytes
item of the structure.long(Value)
for a constant pool entry that is aCONSTANT_Long_info
structure (4.4.5).Value
is thelong
constant represented by thehigh_bytes
andlow_bytes
items of the structure.double(Value)
for a constant pool entry that is aCONSTANT_Double_info
structure (4.4.5).Value
is thedouble
constant represented by thehigh_bytes
andlow_bytes
items of the structure.methodHandle(Kind, Reference)
for a constant pool entry that is aCONSTANT_MethodHandle_info
structure (4.4.8).Kind
is the value of thereference_kind
item of the structure.Reference
is the value of thereference_index
item of the structure.methodType(MethodDescriptor)
for a constant pool entry that is aCONSTANT_MethodType_info
structure (4.4.9).MethodDescriptor
is the method descriptor referenced by thedescriptor_index
item of the structure.dconstant(ConstantName, FieldDescriptor)
for a constant pool entry that is aCONSTANT_Dynamic_info
structure (4.4.10).ConstantName
andFieldDescriptor
correspond to the name and field descriptor referenced by thename_and_type_index
item of the structure. (Thebootstrap_method_attr_index
item is irrelevant to verification.)dmethod(CallSiteName, MethodDescriptor)
for a constant pool entry that is aCONSTANT_InvokeDynamic_info
structure (4.4.10).CallSiteName
andMethodDescriptor
correspond to the name and method descriptor referenced by thename_and_type_index
item of the structure. (Thebootstrap_method_attr_index
item is irrelevant to verification.)
For example, a getfield instruction whose operand refers to a constant pool entry representing a field
foo
of typeF
in classBar
would be represented asgetfield(field(class('Bar', L), 'foo', 'F'))
, whereL
is the class loader of the class containing the instruction. An ldc instruction for loading theint
constant 91 would be represented asldc(int(91))
.
4.10.1.6 Type Checking Methods
A method with a Code
attribute is type safe if it is possible to merge the code and the stack map frames into a single stream such that each stack map frame precedes the instruction it corresponds to, and the merged stream is type correct. The method's exception handlers, if any, must also be legal.
methodIsTypeSafe(Class, Method) :-
parseCodeAttribute(Class, Method, FrameSize, MaxStack,
ParsedCode, Handlers, StackMap),
mergeStackMapAndCode(StackMap, ParsedCode, MergedCode),
methodInitialStackFrame(Class, Method, FrameSize, StackFrame, ReturnType),
Environment = environment(Class, Method, ReturnType, MergedCode,
MaxStack, Handlers),
handlersAreLegal(Environment),
mergedCodeIsTypeSafe(Environment, MergedCode, StackFrame).
Let us consider exception handlers first.
An exception handler is represented by a functor application of the form:
handler(Start, End, Target, ClassName)
whose arguments are, respectively, the start and end of the range of instructions covered by the handler, the first instruction of the handler code, and the name of the exception class that this handler is designed to handle.
An exception handler is legal if there is a stack frame at the start of the handler code (Target
) and the handler's exception class is assignable to the class Throwable
. The exception class of a handler is Throwable
if the handler's class entry is 0, otherwise it is the class named in the handler.
An additional requirement exists for a handler inside an <init>
method if one of the instructions covered by the handler is invokespecial of an <init>
method. In this case, the fact that a handler is running means the object under construction is likely broken, so it is important that the handler does not swallow the exception and allow the enclosing <init>
method to return normally to the caller. Accordingly, the handler is required to either complete abruptly by throwing an exception to the caller of the enclosing <init>
method, or to loop forever.
handlersAreLegal(Environment) :-
exceptionHandlers(Environment, Handlers),
checklist(handlerIsLegal(Environment), Handlers).
handlerIsLegal(Environment, Handler) :-
Handler = handler(Start, End, Target, _),
offsetStackFrame(Environment, Target, _),
currentClassLoader(Environment, CurrentLoader),
handlerExceptionClass(Handler, ExceptionClass, CurrentLoader),
isBootstrapLoader(BL),
isAssignable(ExceptionClass, class('java/lang/Throwable', BL)),
initHandlerIsLegal(Environment, Handler).
handlerExceptionClass(handler(_, _, _, 0),
class('java/lang/Throwable', BL), _) :-
isBootstrapLoader(BL).
handlerExceptionClass(handler(_, _, _, Name),
class(Name, L), L) :-
Name \= 0.
initHandlerIsLegal(Environment, Handler) :-
notInitHandler(Environment, Handler).
notInitHandler(Environment, Handler) :-
Environment = environment(_Class, Method, _, Instructions, _, _),
isNotInit(Method).
notInitHandler(Environment, Handler) :-
Environment = environment(_Class, Method, _, Instructions, _, _),
isInit(Method),
member(instruction(_, invokespecial(CP)), Instructions),
CP = method(MethodClassName, MethodName, Descriptor),
MethodName \= '`<init>`'.
initHandlerIsLegal(Environment, Handler) :-
isInitHandler(Environment, Handler),
sublist(isApplicableInstruction(Target), Instructions,
HandlerInstructions),
noAttemptToReturnNormally(HandlerInstructions).
isInitHandler(Environment, Handler) :-
Environment = environment(_Class, Method, _, Instructions, _, _),
isInit(Method).
member(instruction(_, invokespecial(CP)), Instructions),
CP = method(MethodClassName, '`<init>`', Descriptor).
isApplicableInstruction(HandlerStart, instruction(Offset, _)) :-
Offset >= HandlerStart.
noAttemptToReturnNormally(Instructions) :-
notMember(instruction(_, return), Instructions).
noAttemptToReturnNormally(Instructions) :-
member(instruction(_, athrow), Instructions).
Let us now turn to the stream of instructions and stack map frames.
Merging instructions and stack map frames into a single stream involves four cases:
Merging an empty
StackMap
and a list of instructions yields the original list of instructions.mergeStackMapAndCode([], CodeList, CodeList).
Given a list of stack map frames beginning with the type state for the instruction at
Offset
, and a list of instructions beginning atOffset
, the merged list is the head of the stack map frame list, followed by the head of the instruction list, followed by the merge of the tails of the two lists.mergeStackMapAndCode([stackMap(Offset, Map) | RestMap], [instruction(Offset, Parse) | RestCode], [stackMap(Offset, Map), instruction(Offset, Parse) | RestMerge]) :- mergeStackMapAndCode(RestMap, RestCode, RestMerge).
Otherwise, given a list of stack map frames beginning with the type state for the instruction at
OffsetM
, and a list of instructions beginning atOffsetP
, then, ifOffsetP < OffsetM
, the merged list consists of the head of the instruction list, followed by the merge of the stack map frame list and the tail of the instruction list.mergeStackMapAndCode([stackMap(OffsetM, Map) | RestMap], [instruction(OffsetP, Parse) | RestCode], [instruction(OffsetP, Parse) | RestMerge]) :- OffsetP < OffsetM, mergeStackMapAndCode([stackMap(OffsetM, Map) | RestMap], RestCode, RestMerge).
Otherwise, the merge of the two lists is undefined. Since the instruction list has monotonically increasing offsets, the merge of the two lists is not defined unless every stack map frame offset has a corresponding instruction offset.
To determine if the merged stream for a method is type correct, we first infer the method's initial type state.
The initial type state of a method consists of an empty operand stack and local variable types derived from the type of this
and the arguments, as well as the appropriate flag, depending on whether this is an <init>
method.
methodInitialStackFrame(Class, Method, FrameSize, frame(Locals, [], Flags),
ReturnType):-
methodDescriptor(Method, Descriptor),
parseMethodDescriptor(Descriptor, RawArgs, ReturnType),
expandTypeList(RawArgs, Args),
methodInitialThisType(Class, Method, ThisList),
flags(ThisList, Flags),
append(ThisList, Args, ThisArgs),
expandToLength(ThisArgs, FrameSize, top, Locals).
Given a list of types, the following clause produces a list where every type of size 2 has been substituted by two entries: one for itself, and one top
entry. The result then corresponds to the representation of the list as 32-bit words in the Java Virtual Machine.
expandTypeList([], []).
expandTypeList([Item | List], [Item | Result]) :-
sizeOf(Item, 1),
expandTypeList(List, Result).
expandTypeList([Item | List], [Item, top | Result]) :-
sizeOf(Item, 2),
expandTypeList(List, Result).
flags([uninitializedThis], [flagThisUninit]).
flags(X, []) :- X \= [uninitializedThis].
expandToLength(List, Size, _Filler, List) :-
length(List, Size).
expandToLength(List, Size, Filler, Result) :-
length(List, ListLength),
ListLength < Size,
Delta is Size - ListLength,
length(Extra, Delta),
checklist(=(Filler), Extra),
append(List, Extra, Result).
For the initial type state of an instance method, we compute the type of this
and put it in a list. The type of this
in the <init>
method of Object
is Object
; in other <init>
methods, the type of this
is uninitializedThis
; the type of this
in an instance method of a primitive class is inlinable(N, L)
, where N
is the name of the class containing the method and L
is its defining class loader; otherwise, the type of this
in an instance method is class(N, L)
where .N
is the name of the class containing the method and L
is its defining class loader
For the initial type state of a static method, this
is irrelevant, so the list is empty.
methodInitialThisType(_Class, Method, []) :-
methodAccessFlags(Method, AccessFlags),
member(static, AccessFlags).
methodInitialThisType(Class, Method, [This]) :-
methodAccessFlags(Method, AccessFlags),
notMember(static, AccessFlags),
instanceMethodInitialThisType(Class, Method, This).
instanceMethodInitialThisType(Class, Method, class('java/lang/Object', L)) :-
methodName(Method, '`<init>`'),
classDefiningLoader(Class, L),
classClassName(Class, 'java/lang/Object').
instanceMethodInitialThisType(Class, Method, uninitializedThis) :-
methodName(Method, '`<init>`'),
loadedSuperclasses(Class, Supers),
Supers \= [].
instanceMethodInitialThisType(Class, Method, inlinable(ClassName, L)) :-
classIsPrimitive(Class),
classDefiningLoader(Class, L),
classClassName(Class, ClassName).
instanceMethodInitialThisType(Class, Method, class(ClassName, L)) :-
methodName(Method, MethodName),
MethodName \= '`<init>`',
\+ classIsPrimitive(Class),
classDefiningLoader(Class, L),
classClassName(Class, ClassName).
We now compute whether the merged stream for a method is type correct, using the method's initial type state:
If we have a stack map frame and an incoming type state, the type state must be assignable to the one in the stack map frame. We may then proceed to type check the rest of the stream with the type state given in the stack map frame.
mergedCodeIsTypeSafe(Environment, [stackMap(Offset, MapFrame) | MoreCode], frame(Locals, OperandStack, Flags)) :- frameIsAssignable(frame(Locals, OperandStack, Flags), MapFrame), mergedCodeIsTypeSafe(Environment, MoreCode, MapFrame).
A merged code stream is type safe relative to an incoming type state
T
if it begins with an instructionI
that is type safe relative toT
, andI
satisfies its exception handlers (see below), and the tail of the stream is type safe given the type state following that execution ofI
.NextStackFrame
indicates what falls through to the following instruction. For an unconditional branch instruction, it will have the special valueafterGoto
.ExceptionStackFrame
indicates what is passed to exception handlers.mergedCodeIsTypeSafe(Environment, [instruction(Offset, Parse) | MoreCode], frame(Locals, OperandStack, Flags)) :- instructionIsTypeSafe(Parse, Environment, Offset, frame(Locals, OperandStack, Flags), NextStackFrame, ExceptionStackFrame), instructionSatisfiesHandlers(Environment, Offset, ExceptionStackFrame), mergedCodeIsTypeSafe(Environment, MoreCode, NextStackFrame).
After an unconditional branch (indicated by an incoming type state of
afterGoto
), if we have a stack map frame giving the type state for the following instructions, we can proceed and type check them using the type state provided by the stack map frame.mergedCodeIsTypeSafe(Environment, [stackMap(Offset, MapFrame) | MoreCode], afterGoto) :- mergedCodeIsTypeSafe(Environment, MoreCode, MapFrame).
It is illegal to have code after an unconditional branch without a stack map frame being provided for it.
mergedCodeIsTypeSafe(_Environment, [instruction(_, _) | _MoreCode], afterGoto) :- write_ln('No stack frame after unconditional branch'), fail.
If we have an unconditional branch at the end of the code, stop.
mergedCodeIsTypeSafe(_Environment, [endOfCode(Offset)], afterGoto).
Branching to a target is type safe if the target has an associated stack frame, Frame
, and the current stack frame, StackFrame
, is assignable to Frame
.
targetIsTypeSafe(Environment, StackFrame, Target) :-
offsetStackFrame(Environment, Target, Frame),
frameIsAssignable(StackFrame, Frame).
An instruction satisfies its exception handlers if it satisfies every exception handler that is applicable to the instruction.
instructionSatisfiesHandlers(Environment, Offset, ExceptionStackFrame) :-
exceptionHandlers(Environment, Handlers),
sublist(isApplicableHandler(Offset), Handlers, ApplicableHandlers),
checklist(instructionSatisfiesHandler(Environment, ExceptionStackFrame),
ApplicableHandlers).
An exception handler is applicable to an instruction if the offset of the instruction is greater or equal to the start of the handler's range and less than the end of the handler's range.
isApplicableHandler(Offset, handler(Start, End, _Target, _ClassName)) :-
Offset >= Start,
Offset < End.
An instruction satisfies an exception handler if the instructions's outgoing type state is ExcStackFrame
, and the handler's target (the initial instruction of the handler code) is type safe assuming an incoming type state T
. The type state T
is derived from ExcStackFrame
by replacing the operand stack with a stack whose sole element is the handler's exception class.
instructionSatisfiesHandler(Environment, ExcStackFrame, Handler) :-
Handler = handler(_, _, Target, _),
currentClassLoader(Environment, CurrentLoader),
handlerExceptionClass(Handler, ExceptionClass, CurrentLoader),
/* The stack consists of just the exception. */
ExcStackFrame = frame(Locals, _, Flags),
TrueExcStackFrame = frame(Locals, [ ExceptionClass ], Flags),
operandStackHasLegalLength(Environment, TrueExcStackFrame),
targetIsTypeSafe(Environment, TrueExcStackFrame, Target).
4.10.1.9 Type Checking Instructions
defaultvalue
A defaultvalue 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(defaultvalue(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 the inlinable reference type of the named class on the incoming operand stack, yielding the outgoing type state.
instructionIsTypeSafe(withfield(CP), Environment, _Offset, StackFrame,
NextStackFrame, ExceptionStackFrame) :-
CP = field(FieldClassType, _FieldName, FieldDescriptor),
(FieldClassType = class(FieldClassName, _) ;
FieldClassType = inlinable(FieldClassName, _))
parseFieldDescriptor(FieldDescriptor, FieldType),
currentClassLoader(Environment, CurrentLoader),
validTypeTransition(Environment,
[FieldType, FieldClassType],
inlinable(FieldClassName, CurrentLoader),
StackFrame, NextStackFrame),
exceptionStackFrame(StackFrame, ExceptionStackFrame).
Chapter 5: Loading, Linking, and Initializing
5.1 The Run-Time Constant Pool
The Java Virtual Machine maintains a run-time constant pool for each class and interface (2.5.5). This data structure serves many of the purposes of the symbol table of a conventional programming language implementation. The constant_pool
table in the binary representation of a class or interface (4.4) is used to construct the run-time constant pool upon class or interface creation (5.3).
There are two kinds of entry in the run-time constant pool: symbolic references, which may later be resolved (5.4.3), and static constants, which require no further processing.
The symbolic references in the run-time constant pool are derived from entries in the constant_pool
table in accordance with the structure of each entry:
A symbolic reference to a class, interface, or
arrayreference type is derived from aCONSTANT_Class_info
structure (4.4.1). Such a reference gives the name of a class or interface, or the field descriptor representation ofan arraya reference type, as described in 4.4.1.A symbolic reference to a field of a class or an interface is derived from a
CONSTANT_Fieldref_info
structure (4.4.2). Such a reference 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.A symbolic reference to a method of a class is derived from a
CONSTANT_Methodref_info
structure (4.4.2). Such a reference gives the name and descriptor of the method, as well as a symbolic reference to the class, interface, or array type in which the method is to be found.A symbolic reference to a method of an interface is derived from a
CONSTANT_InterfaceMethodref_info
structure (4.4.2). Such a reference gives the name and descriptor of the interface method, as well as a symbolic reference to the class, interface, or array type in which the method is to be found.A symbolic reference to a method handle is derived from a
CONSTANT_MethodHandle_info
structure (4.4.8). Such a reference gives a symbolic reference to a field of a class or interface, or a method of a class, or a method of an interface, depending on the kind of the method handle.A symbolic reference to a method type is derived from a
CONSTANT_MethodType_info
structure (4.4.9). Such a reference gives a method descriptor (4.3.3).A symbolic reference to a dynamically-computed constant is derived from a
CONSTANT_Dynamic_info
structure (4.4.10). Such a reference gives:a symbolic reference to a method handle, which will be invoked to compute the constant's value;
a sequence of symbolic references and static constants, which will serve as static arguments when the method handle is invoked;
an unqualified name and a field descriptor.
A symbolic reference to a dynamically-computed call site is derived from a
CONSTANT_InvokeDynamic_info
structure (4.4.10). Such a reference gives:a symbolic reference to a method handle, which will be invoked in the course of an invokedynamic instruction (6.5.invokedynamic) to compute an instance of
java.lang.invoke.CallSite
;a sequence of symbolic references and static constants, which will serve as static arguments when the method handle is invoked;
an unqualified name and a method descriptor.
The static constants in the run-time constant pool are also derived from entries in the constant_pool
table in accordance with the structure of each entry:
A string constant is a
reference
to an instance of classString
, and is derived from aCONSTANT_String_info
structure (4.4.3). To derive a string constant, the Java Virtual Machine examines the sequence of code points given by theCONSTANT_String_info
structure:If the method
String.intern
has previously been invoked on an instance of classString
containing a sequence of Unicode code points identical to that given by theCONSTANT_String_info
structure, then the string constant is areference
to that same instance of classString
.Otherwise, a new instance of class
String
is created containing the sequence of Unicode code points given by theCONSTANT_String_info
structure. The string constant is areference
to the new instance. Finally, the methodString.intern
is invoked on the new instance.
Numeric constants are derived from
CONSTANT_Integer_info
,CONSTANT_Float_info
,CONSTANT_Long_info
, andCONSTANT_Double_info
structures (4.4.4, 4.4.5).Note that
CONSTANT_Float_info
structures represent values in IEEE 754 single format andCONSTANT_Double_info
structures represent values in IEEE 754 double format. The numeric constants derived from these structures must thus be values that can be represented using IEEE 754 single and double formats, respectively.
The remaining structures in the constant_pool
table - the descriptive structures CONSTANT_NameAndType_info
, CONSTANT_Module_info
, and CONSTANT_Package_info
, and the foundational structure CONSTANT_Utf8_info
- are only used indirectly when constructing the run-time constant pool. No entries in the run-time constant pool correspond directly to these structures.
Some entries in the run-time constant pool are loadable, which means:
They may be pushed onto the stack by the ldc family of instructions (6.5.ldc, 6.5.ldc_w, 6.5.ldc2_w).
They may be static arguments to bootstrap methods for dynamically-computed constants and call sites (5.4.3.6).
An entry in the run-time constant pool is loadable if it is derived from an entry in the constant_pool
table that is loadable (see Table 4.4-C). Accordingly, the following entries in the run-time constant pool are loadable:
Symbolic references to classes, interfaces, and
arrayreference typesSymbolic references to method handles
Symbolic references to method types
Symbolic references to dynamically-computed constants
Static constants
5.3 Creation and Loading
5.3.5 Deriving a Class from a class
File Representation
Design discussion: this section describes the special handling of the PrimitiveObject
and IdentityObject
interfaces. The strategy outlined here is for the class to be "considered to implement" the interface if it is a certain kind of class and does not already implement the interface explicitly or by inheritance.
Alternatively, we could more uniformly claim that the class is "considered to implement" the expected interface, regardless of what it implements by inheritance. The difference in behavior might be observable, say, via reflection.
An abstract
class implements IdentityObject
if it declares an instance initialization method and does not have its ACC_PRIM_SUPER
flag set; and implements PrimitiveObject
if the opposite is true (ACC_PRIM_SUPER
, no instance initialization method). Instance initialization methods and ACC_PRIM_SUPER
represent two channels for subclass instance creation, and this analysis determines whether only one channel is "open".
Alternatively, we could ignore instance initialization methods and rely entirely on ACC_PRIM_SUPER
. In practice, abstract
classes written in the Java programming language always have instance initialization methods, so the difference in behavior is only relevant to classes produced via other languages or tools.
The class Object
is assumed to be declared abstract
with its ACC_PRIM_SUPER
flag set.
Alternatively, we could leave the class
file of Object
unchanged and call the class out explicitly for special handling.
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 a primitive class or an
abstract
class with itsACC_PRIM_SUPER
flag set, and the class or interface named as the direct superclass of C does not have itsACC_PRIM_SUPER
flag set, 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
.
If C is a primitive class and the interface
PrimitiveObject
is not already a superinterface of C, C is considered to implementPrimitiveObject
.C is a primitive class
C is an
abstract
class with itsACC_PRIM_SUPER
flag set, and C does not declare an instance initializer method (2.9.1)
In these cases, if the
PrimitiveObject
interface has not already been created with the bootstrap class loader, it is created in this phase of loading.If either of the following are true, and the interface
IdentityObject
is not already a superinterface of C, C is considered to implementIdentityObject
.C is an identity class (that is, C is a class that is neither primitive nor
abstract
)C is an
abstract
class that declares an instance initializer method, and C does not have itsACC_PRIM_SUPER
flag set
In these cases, if the
IdentityObject
interface has not already been created with the bootstrap class loader, it is created in this phase of loading.Any exceptions that can be thrown due to class or interface creation can be thrown as a result of this phase of loading. In addition, if C implements both the
PrimitiveObject
interface and theIdentityObject
interface (either explicitly or implicitly, directly or indirectly), this phase of loading throws anIncompatibleClassChangeError
.A concrete class must always implement exactly one of
PrimitiveObject
andIdentityObject
. Anabstract
class or an interface may implement either zero or one ofPrimitiveObject
andIdentityObject
, but not both.
- 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.
During preparation of a class or interface C, the Java Virtual Machine imposes constraints on field and method descriptors (4.3), as follows:
For each occurrence of an InlinableReferenceType in a descriptor of a field or method declared by C, the defining class loader of C is used to create the referenced class or interface.
Any exception that can be thrown as a result of failure of class or interface creation can thus be thrown as a result of failure of preparation.
If the result of creation is not a primitive class, preparation fails with an
IncompatibleClassChangeError
.For each field of C with an inlinable reference type, the type is resolved, as if by resolution of an unresolved symbolic reference to a reference type (5.4.3.1), and the named primitive class is prepared.
Any exception that can be thrown as a result of failure of reference type resolution can thus be thrown as a result of failure of preparation.
If preparation of the primitive class recursively requires preparation of the class C, preparation fails with a
ClassCircularityError
.A primitive class instance is not allowed to "contain" another instance of the same class in an inline form, because the instance could have no finite inline representation. Fields with standard reference types are not intended to support inlining in this way, and so are not subject to this constraint.
After preparation of C, a field of C with an inlinable reference type will hold the default instance of the named primitive class. This step ensures that the class has access to create the default instance, and that the class of the default instance has been prepared.
Note the distinction between steps (1) and (2): step (1) applies to any inlinable reference type appearing in a field or method descriptor, while step (2) only applies to a inlinable reference type that is the type of a field. As a result, an inaccessible inlinable reference type may be used in a method descriptor, or as an array component type in a field descriptor, but may not be used as the type of a field.
Preparation must occur for the primitive class before any user code attempts to access the default instance. We guarantee this by recursively preparing the referenced class. Ideally, initialization will occur as well, per 5.5, before user code accesses the field. But user code may execute during initialization before initialization has a chance to handle the field, so we can't guarantee it.
To do: the circularity check on field types should eventually be dropped for
static
fields, but there are outstanding tricky issues to work out.
During preparation of a class or interface C, the Java Virtual Machine also imposes loading constraints (5.3.4):
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.
Preparation may occur at any time following creation but must be completed prior to initialization.
5.4.3 Resolution
Many Java Virtual Machine instructions - anewarray, checkcast, defaultvalue, 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.
Resolution is the process of dynamically determining one or more concrete values from a symbolic reference in the run-time constant pool. Initially, all symbolic references in the run-time constant pool are unresolved.
Resolution of an unresolved symbolic reference to (i) a class, interface, or array reference type, (ii) a field, (iii) a method, (iv) a method type, (v) a method handle, or (vi) a dynamically-computed constant, proceeds in accordance with the rules given in 5.4.3.1 through 5.4.3.6. In the first three of those sections, the class or interface in whose run-time constant pool the symbolic reference appears is labeled D. Then:
If no error occurs during resolution of the symbolic reference, then resolution succeeds.
Subsequent attempts to resolve the symbolic reference always succeed trivially and result in the same entity produced by the initial resolution. If the symbolic reference is to a dynamically-computed constant, the bootstrap method is not re-executed for these subsequent attempts.
If an error occurs during resolution of the symbolic reference, then it is either (i) an instance of
IncompatibleClassChangeError
(or a subclass);- an instance of
Error
(or a subclass) that arose from resolution or invocation of a bootstrap method; or (iii) an instance ofLinkageError
(or a subclass) that arose because class loading failed or a loader constraint was violated. The error must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference.
Subsequent attempts to resolve the symbolic reference always fail with the same error that was thrown as a result of the initial resolution attempt. If the symbolic reference is to a dynamically-computed constant, the bootstrap method is not re-executed for these subsequent attempts.
- an instance of
Because errors occurring on an initial attempt at resolution are thrown again on subsequent attempts, a class in one module that attempts to access, via resolution of a symbolic reference in its run-time constant pool, an unexported
public
type in a different module will always receive the same error indicating an inaccessible type (5.4.4), even if the Java SE Platform API is used to dynamically export thepublic
type's package at some time after the class's first attempt.
Resolution of an unresolved symbolic reference to a dynamically-computed call site proceeds in accordance with the rules given in 5.4.3.6. Then:
If no error occurs during resolution of the symbolic reference, then resolution succeeds solely for the instruction in the
class
file that required resolution. This instruction necessarily has an opcode of invokedynamic.Subsequent attempts to resolve the symbolic reference by that instruction in the
class
file always succeed trivially and result in the same entity produced by the initial resolution. The bootstrap method is not re-executed for these subsequent attempts.The symbolic reference is still unresolved for all other instructions in the
class
file, of any opcode, which indicate the same entry in the run-time constant pool as the invokedynamic instruction above.If an error occurs during resolution of the symbolic reference, then it is either (i) an instance of
IncompatibleClassChangeError
(or a subclass);- an instance of
Error
(or a subclass) that arose from resolution or invocation of a bootstrap method; or (iii) an instance ofLinkageError
(or a subclass) that arose because class loading failed or a loader constraint was violated. The error must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference.
Subsequent attempts by the same instruction in the
class
file to resolve the symbolic reference always fail with the same error that was thrown as a result of the initial resolution attempt. The bootstrap method is not re-executed for these subsequent attempts.The symbolic reference is still unresolved for all other instructions in the
class
file, of any opcode, which indicate the same entry in the run-time constant pool as the invokedynamic instruction above.- an instance of
Certain of the instructions above require additional linking checks when resolving symbolic references. For instance, in order for a getfield instruction to successfully resolve the symbolic reference to the field on which it operates, it must not only complete the field resolution steps given in 5.4.3.2 but also check that the field is not static
. If it is a static
field, a linking exception must be thrown.
Linking exceptions generated by checks that are specific to the execution of a particular Java Virtual Machine instruction are given in the description of that instruction and are not covered in this general discussion of resolution. Note that such exceptions, although described as part of the execution of Java Virtual Machine instructions rather than resolution, are still properly considered failures of resolution.
5.4.3.1 Class, Interface, and Array Reference Type Resolution
To resolve an unresolved symbolic reference from D to a class or interface C denoted by N, the following steps are performed:
The defining class loader of D is used to create a class or interface denoted by N. This class or interface is C. The details of the process are given in 5.3.
Any exception that can be thrown as a result of failure of class or interface creation can thus be thrown as a result of failure of class and interface resolution.
Access control is applied for the access from D to C (5.4.4).
To resolve an unresolved symbolic reference from D to an array a reference type T, the following steps are performed:
If the element type of the array type is a class or interface typeFor any class or interface name N mentioned by the symbolic reference's descriptor (4.3.2),the named class or interfaceN is resolved, as if by resolution of an unresolved symbolic reference tothe nameda class or interface N.For any occurrence of an InlinableReferenceType in the descriptor, if the resolved class is not a primitive class, resolution fails with an
IncompatibleClassChangeError
.A representation of the
arrayreference type denoted by the symbolic reference is created.
If resolution of a class, interface, or array reference type successfully loads a class or interface, but a subsequent step (such as access checking) fails, the class or interface is still valid and usable. Nevertheless, resolution fails, and the symbolic reference that was being resolved is invalid.
5.4.3.1 Field Resolution
Design discussion: we do not introduce any constraints on the classes named by inlinable types in field (or method) reference descriptors. Thus, a field reference with a type like Qjava/lang/String;
is permitted. Since it's impossible to declare a field with such a type (see 5.4.2), resolution of the reference will fail anyway with a NoSuchFieldError
.
Alternatively, we could more strictly validate the Q
descriptor before performing a search, and resolution would fail with an IncompatibleClassChangeError
. (Extra class loading would be called for, too, but if the the referenced field exists and is valid, the named class has already been loaded and confirmed to be primitive.)
5.4.3.5 Method Type and Method Handle Resolution
To resolve an unresolved symbolic reference to a method type, it is as if resolution occurs of unresolved symbolic references to classes and interfaces (5.4.3.1) whose names are mentioned by the method descriptor (4.3.3), in the order in which they are mentioned.
Any exception that can be thrown as a result of failure of resolution of a reference to a class or interface can thus be thrown as a result of failure of method type resolution.
For each occurrence of an InlinableReferenceType in the method descriptor, if the resolved class is not a primitive class, resolution fails with an IncompatibleClassChangeError
.
The result of successful method type resolution is a reference
to an instance of java.lang.invoke.MethodType
which represents the method descriptor.
Method type resolution occurs regardless of whether the run-time constant pool actually contains symbolic references to classes and interfaces indicated in the method descriptor. Also, the resolution is deemed to occur on unresolved symbolic references, so a failure to resolve one method type will not necessarily lead to a later failure to resolve another method type with the same textual method descriptor, if suitable classes and interfaces can be loaded by the later time.
Resolution of an unresolved symbolic reference to a method handle is more complicated. Each method handle resolved by the Java Virtual Machine has an equivalent instruction sequence called its bytecode behavior, indicated by the method handle's kind. The integer values and descriptions of the nine kinds of method handle are given in Table 5.4.3.5-A.
Symbolic references by an instruction sequence to fields or methods are indicated by C.x:T
, where x
and T
are the name and descriptor (4.3.2, 4.3.3) of the field or method, and C
is the class, interface, or array type in which the field or method is to be found.
Table 5.4.3.5-A. Bytecode Behaviors for Method Handles
Kind | Description | Interpretation |
---|---|---|
1 | REF_getField |
getfield C.f:T |
2 | REF_getStatic |
getstatic C.f:T |
3 | REF_putField |
putfield C.f:T |
4 | REF_putStatic |
putstatic C.f:T |
5 | REF_invokeVirtual |
invokevirtual C.m:(A*)T |
6 | REF_invokeStatic |
invokestatic C.m:(A*)T |
7 | REF_invokeSpecial |
invokespecial C.m:(A*)T |
8 | REF_newInvokeSpecial |
new C; dup; invokespecial C.<init>:(A*)V |
9 | REF_invokeInterface |
invokeinterface C.m:(A*)T |
Let MH be the symbolic reference to a method handle (5.1) being resolved. Also:
Let R be the symbolic reference to a field or method given by MH.
For example, R is a symbolic reference to C
.
f for bytecode behavior of kind 1, and a symbolic reference to C.
<init>
for bytecode behavior of kind 8.Let C be the class, interface, or array type referenced by R.
Let T be the type given by the field descriptor of R, or the return type given by the method descriptor of R. Let A* be the sequence (perhaps empty) of parameter types given by the method descriptor of R.
To resolve MH, all symbolic references to classes, interfaces, array types, fields, and methods in MH's bytecode behavior are resolved, using the following four steps:
R is resolved. This occurs as if by field resolution (5.4.3.2) when MH's bytecode behavior is kind 1, 2, 3, or 4, and as if by method resolution (5.4.3.3) when MH's bytecode behavior is kind 5, 6, 7, or 8, and as if by interface method resolution (5.4.3.4) when MH's bytecode behavior is kind 9.
The following constraints apply to the result of resolving R. These constraints correspond to those that would be enforced during verification or execution of the instruction sequence for the relevant bytecode behavior.
If MH's bytecode behavior is kind 7 (
REF_invokeSpecial
), then C must be the current class or interface, a superclass of the current class, a direct superinterface of the current class or interface, orObject
.If MH's bytecode behavior is kind 8 (
REF_newInvokeSpecial
), then R must resolve to an instance initialization method declared in class C.If R resolves to a
protected
member, then the following rules apply depending on the kind of MH's bytecode behavior:For kinds 1, 3, and 5 (
REF_getField
,REF_putField
, andREF_invokeVirtual
): IfC.f
orC.m
resolved to aprotected
field or method, and C is a class in in a different run-time package than the current class, then C must be a subclass of the current class.For kind 8 (
REF_newInvokeSpecial
): If C.
<init>
resolved to aprotected
method, then C must be declared in the same run-time package as the current class.
R must resolve to a
static
or non-static
member depending on the kind of MH's bytecode behavior:For kinds 1, 3, 5, 7, and 9 (
REF_getField
,REF_putField
,REF_invokeVirtual
,REF_invokeSpecial
, andREF_invokeInterface
):C.f
orC.m
must resolve to a non-static
field or method.For kinds 2, 4, and 6 (
REF_getStatic
,REF_putStatic
, andREF_invokeStatic
):C.f
orC.m
must resolve to astatic
field or method.
A reference to an instance of
java.lang.invoke.MethodType
is obtained as if by resolution of an unresolved symbolic reference to a method type that contains the method descriptor specified in Table 5.4.3.5-B for the kind of MH.It is as if the symbolic reference to a method handle contains a symbolic reference to the method type that the resolved method handle will eventually have. The detailed structure of the method type is obtained by inspecting Table 5.4.3.5-B.
Table 5.4.3.5-B. Method Descriptors for Method Handles
Kind Description Method descriptor 1 REF_getField
(C)T
2 REF_getStatic
()T
3 REF_putField
(C,T)V
4 REF_putStatic
(T)V
5 REF_invokeVirtual
(C,A*)T
6 REF_invokeStatic
(A*)T
7 REF_invokeSpecial
(C,A*)T
8 REF_newInvokeSpecial
(A*)C
9 REF_invokeInterface
(C,A*)T
In steps 1 and 3, any exception that can be thrown as a result of failure of resolution of a symbolic reference to a class, interface, field, or method, or method type can be thrown as a result of failure of method handle resolution. In step 2, any failure due to the specified constraints causes a failure of method handle resolution due to an IllegalAccessError
.
The intent is that resolving a method handle can be done in exactly the same circumstances that the Java Virtual Machine would successfully verify and resolve the symbolic references in the bytecode behavior. In particular, method handles to
private
,protected
, andstatic
members can be created in exactly those classes for which the corresponding normal accesses are legal.
The result of successful method handle resolution is a reference
to an instance of java.lang.invoke.MethodHandle
which represents the method handle MH.
The type descriptor of this java.lang.invoke.MethodHandle
instance is the java.lang.invoke.MethodType
instance produced in the third step of method handle resolution above.
The type descriptor of a method handle is such that a valid call to
invokeExact
injava.lang.invoke.MethodHandle
on the method handle has exactly the same stack effects as the bytecode behavior. Calling this method handle on a valid set of arguments has exactly the same effect and returns the same result (if any) as the corresponding bytecode behavior.
If the method referenced by R has the ACC_VARARGS
flag set (4.6), then the java.lang.invoke.MethodHandle
instance is a variable arity method handle; otherwise, it is a fixed arity method handle.
A variable arity method handle performs argument list boxing (JLS §15.12.4.2) when invoked via invoke
, while its behavior with respect to invokeExact
is as if the ACC_VARARGS
flag were not set.
Method handle resolution throws an IncompatibleClassChangeError
if the method referenced by R has the ACC_VARARGS
flag set and either A* is an empty sequence or the last parameter type in A* is not an array type. That is, creation of a variable arity method handle fails.
An implementation of the Java Virtual Machine is not required to intern method types or method handles. That is, two distinct symbolic references to method types or method handles which are structurally identical might not resolve to the same instance of java.lang.invoke.MethodType
or java.lang.invoke.MethodHandle
respectively.
The
java.lang.invoke.MethodHandles
class in the Java SE Platform API allows creation of method handles with no bytecode behavior. Their behavior is defined by the method ofjava.lang.invoke.MethodHandles
that creates them. For example, a method handle may, when invoked, first apply transformations to its argument values, then supply the transformed values to the invocation of another method handle, then apply a transformation to the value returned from that invocation, then return the transformed value as its own result.
5.5 Initialization
Design discussion: this section specifies the initialization of primitive classes named by inlinable reference types in the defaultvalue, anewarray, and multianewarray instructions, as a prerequesite to creating a default instance.
For the anewarray and multianewarray instructions, 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 an inlinable reference type is mentioned by an array type, even when no inlinable-typed 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, defaultvalue, anewarray, multianewarray, getstatic, putstatic, or invokestatic that references C (6.5.new, 6.5.defaultvalue, 6.5.anewarray, 6.5.multianewarray, 6.5.getstatic, 6.5.putstatic, 6.5.invokestatic).
Upon execution of a new instruction, the class to be initialized is the class referenced by the instruction.
Upon execution of a defaultvalue instruction, the class to be initialized is the class named by the referenced inlinable reference type.
Upon execution of an anewarray instruction, if the instruction references an inlinable reference type, the class to be initialized is the named primitive class.
Upon execution of a multianewarray instruction, if the instruction references an array type whose element type is an inlinable reference type, and the dimensions operand of the instruction matches the number of dimensions of the array type, the class to be initialized is the named primitive class.
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.If C is a primitive class, the initialization of a class that declares a field whose type is the inlinable reference type of C.
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 has an inlinable reference type referencing a class F, recursively perform this entire procedure for F. If necessary, verify and prepare F first.Initialization of F is necessary because the initial value of the field is the default 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
Design discussion: the aastore instruction throws a NullPointerException
on an attempt to store null
in an inlinable-type array.
Alternatively, we could have the instruction throw ArrayStoreException
.
- 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 an inlinable reference type, 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 an inlinable reference type, aastore throws aNullPointerException
.Otherwise, if the non-
null
value is not a value of the array component type, aastore throws anArrayStoreException
.
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, orarrayreference type.The named class, interface, or
arrayreference type is resolved (5.4.3.1). An array component type is determined from the symbolic reference: if the symbolic reference is to a class or interface, the array component type is the standard reference type of the referenced class or interface; if the symbolic reference is to a reference type, the array component type is the resolved type.If the array component type is an inlinable reference type, the resolved class named by the type is initialized if it has not already been initialized (5.5).
A new array
with component type given by the resolved class, interface, or array typewith the given component type, of length count, is allocated from the garbage-collected heap, and areference
arrayref to this new array object is pushed onto the operand stack. All components of the new array are initialized tothe default valuenull
,forof the component type (2.4).reference
types- Linking Exceptions
During resolution of the symbolic reference to the class, interface, or
arrayreference type, any of the exceptions documented in 5.4.3.1 can be thrown.- Run-time Exceptions
Otherwise, if execution of this anewarray instruction causes initialization of a referenced primitive class, anewarray may throw an
Error
as detailed in 5.5.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.
checkcast
Design discussion: the checkcast instruction throws a NullPointerException
on an attempt to cast null
to an inlinable reference type.
Alternatively, we could have the instruction throw ClassCastException
.
- Operation
Check whether object is of given type
- Format
checkcast
indexbyte1
indexbyte2- Forms
checkcast = 192 (0xc0)
- Operand Stack
..., objectref →
..., objectref
- Description
The objectref must be of type
reference
. 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, orarrayreference type.If objectref is
null
and the symbolic reference does not name a inlinable reference type, then the operand stack is unchanged.OtherwiseIf objectref is notnull
, the named class, interface, orarrayreference type is resolved (5.4.3.1). A checked type is determined from the symbolic reference: if the symbolic reference is to a class or interface, the checked type is the standard reference type of the referenced class or interface; if the symbolic reference is to a reference type, the checked type is the resolved type. If objectref is a value of thetype given by the resolved class, interface, or array typechecked type, the operand stack is unchanged.The following rules are used to determine whether a reference to an object is a value of a reference type, T.
If the reference is to an instance of a class C, then:
If T is
the type ofa standard or inlinable reference type of a class D, then the reference is a value of T if C is D or a subclass of D.If T is the type of an interface I, then the reference is a value of T if C implements I.
If the reference is to an array with component type SC, then:
If T is a class type, then the reference is a value of T if T is
Object
.If T is an interface type, then the reference is a value of T if T is
Cloneable
orjava.io.Serializable
(as loaded by the bootstrap class loader).If T is an array type TC
[]
, that is, an array of components of type TC, then the reference is a value of T if one of the following are true:TC and SC are the same type.
TC is the class type
Object
.TC is a standard reference class type, SC is a standard or inlinable reference class type, and the class of SC is a subclass of the class of TC.
TC is a standard reference class type and SC is the inlinable reference type of the same class.
TC is an interface type, SC is a class type, and the class of SC implements the interface of TC.
TC is an interface type, SC is an interface type, and the interface of SC extends the interface of TC.
TC is the interface type
Cloneable
orjava.io.Serializable
(as loaded by the bootstrap class loader), and SC is an array type.TC is an array type TCC
[]
, SC is an array type SCC[]
, and one of these tests of array component types apply recursively to TCC and SCC.
- Linking Exceptions
During resolution of the symbolic reference to the class, interface, or
arrayreference type, any of the exceptions documented in 5.4.3.1 can be thrown.- Run-time Exception
Otherwise, if objectref is
null
and the symbolic reference names an inlinable reference type, the checkcast instruction throws aNullPointerException
.Otherwise, if objectref is not null and is not a value of the
type given by the resolved class, interface, or array typechecked type, the checkcast instruction throws aClassCastException
.- Notes
The checkcast instruction is very similar to the instanceof instruction (6.5.instanceof). It differs in its treatment of
null
, its behavior when its test fails (checkcast throws an exception, instanceof pushes a result code), and its effect on the operand stack.
defaultvalue
Design discussion: the defaultvalue instruction produces the default value of an inlinable reference type.
Alternatively, it could be expanded to support all reference types. (The default value of any standard reference or array type is always null
.)
Or the instruction could be reframed to produce the default instance of a given class. In that case, the CONSTANT_Class
would need to reference a plain class name (not a Q
descriptor), and the named class would be required to be primitive.
The design will need to anticipate that, in the future, the default value of a parameterized primitive class type will depend on the parameterization. (The default value of Wrapper[String]
is a wrapper for null
, while the default value of Wrapper[int]
is a wrapper for 0.)
Orthogonally, another name like aconst_default might fit more cleanly into the existing instruction set.
- Operation
Push default value of an inlinable reference type
- Format
defaultvalue
indexbyte1
indexbyte2- Forms
defaultvalue = 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 an inlinable reference type.The referenced type is resolved (5.4.3.1). The named primitive class is initialized if it has not already been initialized (5.5).
A
reference
to an instance of the primitive 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 inlinable reference type, any of the exceptions documented in 5.4.3.1 can be thrown.
- Run-time Exception
Otherwise, if execution of this defaultvalue instruction causes initialization of the referenced class, defaultvalue may throw an
Error
as detailed in 5.5.- Notes
The defaultvalue instruction is similar to the new instruction. But unlike new, the class instance created by defaultvalue is completely initialized—there is no need to invoke an instance initialization method.
Default instances of primitive classes are also created implicitly when fields or array components with the inlinable reference type of the class are initialized, via new, anewarray, multianewarray, or class preparation (5.4.2). Any class that can successfully resolve a reference to the primitive class can also create a default instance.
The withfield instruction is used to create primitive class instances other than the default 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 class instances or arrays with the same identity (2.4).
Both references are to instances of the same primitive 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 primitive object may occur to an arbitrary depth (although it must eventually terminate—circular primitive objects are impossible to create). And an attacker with the ability to create arbitrary primitive class instances can use if_acmpeq to infer the contents of a private
field.
instanceof
- Operation
Determine if object is of given type
- Format
instanceof
indexbyte1
indexbyte2- Forms
instanceof = 193 (0xc1)
- Operand Stack
..., objectref →
..., result
- Description
The objectref, which must be of type
reference
, is popped from the operand stack. 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.If objectref is
null
, the instanceof instruction pushes anint
result of 0 onto the operand stack.OtherwiseIf objectref is notnull
, the named class, interface, orarrayreference type is resolved (5.4.3.1). A checked type is determined from the symbolic reference: if the symbolic reference is to a class or interface, the checked type is the standard reference type of the referenced class or interface; if the symbolic reference is to a reference type, the checked type is the resolved type. If objectref is a value of thetype given by the resolved class, interface, or array typechecked type, the instanceof instruction pushes anint
result of 1 onto the operand stack; otherwise, it pushes anint
result of 0.Whether objectref is a value of the
type given by the resolved class, interface, or array typechecked type is determined according to the rules given for checkcast.- Linking Exceptions
During resolution of the symbolic reference to the class, interface, or
arrayreference type, any of the exceptions documented in 5.4.3.1 can be thrown.- Notes
The instanceof instruction is very similar to the checkcast instruction (6.5.checkcast). It differs in its treatment of
null
, its behavior when its test fails (checkcast throws an exception, instanceof pushes a result code), and its effect on the operand stack.
ldc
- Operation
Push item from run-time constant pool
- Format
ldc
index- Forms
ldc = 18 (0x12)
- Operand Stack
... →
..., value
- Description
The index is an unsigned byte that must be a valid index into the run-time constant pool of the current class (2.5.5). The run-time constant pool entry at index must be loadable (5.1), and not any of the following:
A numeric constant of type
long
ordouble
.A symbolic reference to a dynamically-computed constant whose field descriptor is
J
(denotinglong
) orD
(denotingdouble
).
If the run-time constant pool entry is a numeric constant of type
int
orfloat
, then the value of that numeric constant is pushed onto the operand stack as anint
orfloat
, respectively.Otherwise, if the run-time constant pool entry is a string constant, that is, a
reference
to an instance of classString
, then value, areference
to that instance, is pushed onto the operand stack.Otherwise, if the run-time constant pool entry is a symbolic reference to a class, interface, or
arrayreference type, then the symbolic reference is resolved (5.4.3.1) and value, areference
to theClass
object representing that class, interface, orarrayreference type, is pushed onto the operand stack. If the symbolic reference is to a class or interface, value represents the standard reference type of the referenced class or interface.Otherwise, the run-time constant pool entry is a symbolic reference to a method type, a method handle, or a dynamically-computed constant. The symbolic reference is resolved (5.4.3.5, 5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.
- Linking Exceptions
During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.
- Notes
The ldc instruction can only be used to push a value of type
float
taken from the float value set (2.3.2) because a constant of typefloat
in the constant pool (4.4.4) must be taken from the float value set.
ldc_w
- Operation
Push item from run-time constant pool (wide index)
- Format
ldc_w
indexbyte1
indexbyte2- Forms
ldc_w = 19 (0x13)
- Operand Stack
... →
..., value
- Description
The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.5.5), where the value of the index is calculated as (indexbyte1
<<
8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at the index must be loadable (5.1), and not any of the following:A numeric constant of type
long
ordouble
.A symbolic reference to a dynamically-computed constant whose field descriptor is
J
(denotinglong
) orD
(denotingdouble
).
If the run-time constant pool entry is a numeric constant of type
int
orfloat
, or a string constant, then value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.Otherwise, the run-time constant pool entry is a symbolic reference to a class, interface,
arrayreference type, method type, method handle, or dynamically-computed constant. It is resolved and value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.- Linking Exceptions
During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.
- Notes
The ldc_w instruction is identical to the ldc instruction (6.5.ldc) except for its wider run-time constant pool index.
The ldc_w instruction can only be used to push a value of type
float
taken from the float value set (2.3.2) because a constant of typefloat
in the constant pool (4.4.4) must be taken from the float value set.
monitorenter
- Operation
Enter monitor for object
- Format
monitorenter
- Forms
monitorenter = 194 (0xc2)
- Operand Stack
..., objectref →
...
- Description
The objectref must be of type
reference
.Each
objectinstance of an identity class, and each array, 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 primitive class instance, 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 class instance or array 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 primitive class instance, monitorexit throws an
IllegalMonitorStateException
.Otherwise, if the thread that executes monitorexit is not the owner of the monitor associated with the
instanceidentity class instance or array 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).
multianewarray
- Operation
Create new multidimensional array
- Format
multianewarray
indexbyte1
indexbyte2
dimensions- Forms
multianewarray = 197 (0xc5)
- Operand Stack
..., count1, [count2, ...] →
..., arrayref
- Description
The dimensions operand is an unsigned byte that must be greater than or equal to 1. It represents the number of dimensions of the array to be created. The operand stack must contain dimensions values. Each such value represents the number of components in a dimension of the array to be created, must be of type
int
, and must be non-negative. The count1 is the desired length in the first dimension, count2 in the second, etc.All of the count values are popped off the operand stack. 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 an array type. The referenced array type is resolved (5.4.3.1). The resulting entry must be an array type of dimensionality greater than or equal to dimensions.If the array type has an inlinable reference element type, and dimensions matches the number of dimensions of the array type, the named primitive class is initialized if it has not already been initialized (5.5).
A new multidimensional array of the array type is allocated from the garbage-collected heap. If any count value is zero, no subsequent dimensions are allocated. The components of the array in the first dimension are initialized to subarrays of the type of the second dimension, and so on. The components of the last allocated dimension of the array are initialized to the default initial value (2.3, 2.4) for the component type of that dimension. A
reference
arrayref to the new array is pushed onto the operand stack.- Linking Exceptions
During resolution of the symbolic reference to the array type, any of the exceptions documented in 5.4.3.1 can be thrown.
- Run-time Exception
Otherwise, if execution of this multianewarray instruction causes initialization of a referenced primitive class, multianewarray may throw an
Error
as detailed in 5.5.Otherwise, if any of the dimensions values on the operand stack are less than zero, the multianewarray instruction throws a
NegativeArraySizeException
.- Notes
It may be more efficient to use newarray or anewarray (6.5.newarray, 6.5.anewarray) when creating an array of a single dimension.
The array type referenced via the run-time constant pool may have more dimensions than the dimensions operand of the multianewarray instruction. In that case, only the first dimensions of the dimensions of the array are created.
new
Design discussion: new may not be applied to a primitive class. In addition, the behavior of new when applied to the class Object
is modified. Our solution anticipates a class java.lang.Identity
which implements IdentityObject
. The instruction new java/lang/Object
allocates an instance of Identity
, which will become fully initialized upon a call to Object.<init>:()V
. (The constructor of Identity
is expected to be empty, and will not be executed by code following this pattern.)
Alternatively, we may prefer not to specify the precise class to be instantiated. In that approach, we would instead describe some properties of the expected class (no instance fields or methods, "empty" constructor, ...), and then claim that the instruction produces an instance of such a class.
The "Notes" section motivates the special treatment of Object
by claiming that the class is abstract
. Alternatively, we could keep Object
as a concrete class, and merely claim that it is "effectively abstract".
- Operation
Create new 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).MemoryIf the named class is an identity class, 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, areference
to the instance, is pushed onto the operand stack.If the named class is
Object
, memory for a new instance of the classIdentity
is allocated from the garbage-collected heap. The objectref, areference
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 a primitive 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.
A modern
class
file should avoid applying the new opcode to the classObject
, which isabstract
and cannot be instantiated directly. However, for compatibility with bytecode written whenObject
was notabstract
, the Java Virtual Machine supports these instructions by creating instances of the classIdentity
. The verifier will expect the instruction to be followed by an invocation of the instance initialization method ofObject
, notIdentity
, but this anomaly is tolerable because theIdentity
class requires no initialization.
withfield
Design discussion: use of the withfield instruction is restricted to nestmates of the field's declaring class. This prevents unauthorized creation of primitive 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 factory 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 primitive class instance 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 primitive 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 the primitive 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 primitive 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 primitive classes declared outside of the current class's nest. Those classes may declare factory methods (2.9.4) or other mechanisms to provide classes outside of the nest with a controlled path for instance creation.