Copyright © 2017 Oracle America, Inc. Legal Notice.
This document proposes changes to the Java Virtual Machine Specification to allow access to private
class members from related "nestmate" classes. See JEP 181 for an overview.
There are two major changes:
Introducing the NestHost
and NestMembers
attributes. Modifying the accessibility rules to determine the nest membership of a class and to allow private
members within a nest to be referenced.
invokeinterface
to support invocation of private
methods.The following five instructions invoke methods:
invokevirtual
invokes an instance method of an object, dispatching on the (virtual) type of the object. This is the normal method dispatch in the Java programming language.
invokeinterface
invokes an interface method, searching the methods implemented by the particular run-time object to find the appropriate method.
invokespecial
invokes an instance method requiring special handling, whether either an instance initialization method (2.9.1), a or a method of the current class or its supertypes.private
method, or a superclass method
invokestatic
invokes a class (static
) method in a named class.
invokedynamic
invokes the method which is the target of the call site object bound to the invokedynamic
instruction. The call site object was bound to a specific lexical occurrence of the invokedynamic
instruction by the Java Virtual Machine as a result of running a bootstrap method before the first execution of the instruction. Therefore, each occurrence of an invokedynamic
instruction has a unique linkage state, unlike the other instructions which invoke methods.
The method return instructions, which are distinguished by return type, are ireturn
(used to return values of type boolean
, byte
, char
, short
, or int
), lreturn
, freturn
, dreturn
, and areturn
. In addition, the return
instruction is used to return from methods declared to be void, instance initialization methods, and class or interface initialization methods.
...
The invokespecial
instruction must be used to invoke instance initialization methods (3.8). It is also used when invoking methods in the superclass (super
) and when invoking . For instance, given classes private
methodsNear
and Far
declared as:
class Near {
int it;
public int getItNear() {
return getIt();
}
private int getIt() {
return it;
}
}
class Far extends Near {
int getItFar() {
return super.getItNear();
}
}
class Near {
int it;
int getItNear() {
return it;
}
}
class Far extends Near {
int getItFar() {
return super.getItNear();
}
}
the method Near.getItNear
(which invokes a private method) becomes:
Method int getItNear()
0 aload_0
1 invokespecial #5 // Method Near.getIt()I
4 ireturn
The method Far.getItFar
(which invokes a superclass method) becomes:
Method int getItFar()
0 aload_0
1 invokespecial #4 // Method Near.getItNear()I
4 ireturn
Note that methods called using the invokespecial
instruction always pass this
to the invoked method as its first argument. As usual, it is received in local variable 0.
Because private
methods may now be invoked from a nestmate class, it is no longer recommended to compile their invocation to invokespecial
. (invokespecial
may only be used for methods declared in the current class or a superclass.) A standard usage of invokevirtual
or invokeinterface
works just fine instead, with no special discussion necessary.
...
Attributes are used in the ClassFile
, field_info
, method_info
, and Code_attribute
structures of the class
file format (4.1, 4.5, 4.6, 4.7.3).
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
must be a valid unsigned 16-bit index into the constant pool of the class. The constant_pool
entry at attribute_name_index
must be a CONSTANT_Utf8_info
structure (4.4.7) representing the name of the attribute. The value of the attribute_length
item indicates the length of the subsequent information in bytes. The length does not include the initial six bytes that contain the attribute_name_index
and attribute_length
items.
26 28 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 accompanied by the first version of the class
file format in which it was defined, and the corresponding version of the Java SE platform. (For old class
file versions, the JDK release is used instead of the Java SE platform version).
Table 4.7-B is orderd ordered by the first version of the class
file format in which each attribute was defined.
Table 4.7-C is ordered by the location in a class
file where each attribute is defined to appear.
Within the context of their use in this specification, that is, in the attributes
tables of the class
file structures in which they appear, the names of these predefined attributes are reserved.
Any conditions on the presence of a predefined attribute in an attributes
table are specified explicitly in the section which describes the attribute. If no conditions are specified, then the attribute may appear any number of times in an attributes
table.
The predefined attributes are categorized into three groups according to their purpose:
Five Seven attributes are critical to correct interpretation of the class
file by the Java Virtual Machine:
ConstantValue
Code
StackMapTable
Exceptions
BootstrapMethods
NestHost
NestMembers
In a class
file of version V, each of these attributes must be recognized and correctly read by an implementation of the Java Virtual Machine if the implementation recognizes class
files of version V, and V is at least the version where the attribute was first defined, and the attribute appears in a location where it is defined to appear.
Eight attributes are not critical to correct interpretation of the class
file by the Java Virtual Machine, but are either critical to correct interpretation of the class
file by the class libraries of the Java SE Platform, or are useful for tools (in which case the section that specifies an attribute describes it as "optional"):
InnerClasses
EnclosingMethod
Synthetic
Signature
SourceFile
LineNumberTable
LocalVariableTable
LocalVariableTypeTable
In a class
file of version V, each of these attributes must be recognized and correctly read by an implementation of the Java Virtual Machine if the implementation recognizes class
files of version V, and V is at least the version where the attribute was first defined, and the attribute appears in a location where it is defined to appear.
Thirteen attributes are not critical to correct interpretation of the class
file by the Java Virtual Machine, but contain metadata about the class
file that is either exposed by the class libraries of the Java SE Platform, or made available by tools (in which case the section that specifies an attribute describes it as "optional"):
SourceDebugExtension
Deprecated
RuntimeVisibleAnnotations
RuntimeInvisibleAnnotations
RuntimeVisibleParameterAnnotations
RuntimeInvisibleParameterAnnotations
RuntimeVisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations
AnnotationDefault
MethodParameters
Module
ModulePackages
ModuleMainClass
An implementation of the Java Virtual Machine may use the information that these attributes contain, or otherwise must silently ignore these attributes.
Table 4.7-A. Predefined class
file attributes (by section)
Attribute | Section | class file |
Java SE |
---|---|---|---|
ConstantValue |
4.7.2 | 45.3 | 1.0.2 |
Code |
4.7.3 | 45.3 | 1.0.2 |
StackMapTable |
4.7.4 | 50.0 | 6 |
Exceptions |
4.7.5 | 45.3 | 1.0.2 |
InnerClasses |
4.7.6 | 45.3 | 1.1 |
EnclosingMethod |
4.7.7 | 49.0 | 5.0 |
Synthetic |
4.7.8 | 45.3 | 1.1 |
Signature |
4.7.9 | 49.0 | 5.0 |
SourceFile |
4.7.10 | 45.3 | 1.0.2 |
SourceDebugExtension |
4.7.11 | 49.0 | 5.0 |
LineNumberTable |
4.7.12 | 45.3 | 1.0.2 |
LocalVariableTable |
4.7.13 | 45.3 | 1.0.2 |
LocalVariableTypeTable |
4.7.14 | 49.0 | 5.0 |
Deprecated |
4.7.15 | 45.3 | 1.1 |
RuntimeVisibleAnnotations |
4.7.16 | 49.0 | 5.0 |
RuntimeInvisibleAnnotations |
4.7.17 | 49.0 | 5.0 |
RuntimeVisibleParameterAnnotations |
4.7.18 | 49.0 | 5.0 |
RuntimeInvisibleParameterAnnotations |
4.7.19 | 49.0 | 5.0 |
RuntimeVisibleTypeAnnotations |
4.7.20 | 52.0 | 8 |
RuntimeInvisibleTypeAnnotations |
4.7.21 | 52.0 | 8 |
AnnotationDefault |
4.7.22 | 49.0 | 5.0 |
BootstrapMethods |
4.7.23 | 51.0 | 7 |
MethodParameters |
4.7.24 | 52.0 | 8 |
Module |
4.7.25 | 53.0 | 9 |
ModulePackages |
4.7.26 | 53.0 | 9 |
ModuleMainClass |
4.7.27 | 53.0 | 9 |
NestHost |
4.7.28 | 55.0 | 11 |
NestMembers |
4.7.29 | 55.0 | 11 |
Table 4.7-B. Predefined class
file attributes (by class
file version)
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 |
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 |
ClassFile |
55.0 |
NestMembers |
ClassFile |
55.0 |
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 |
Synthetic |
ClassFile , field_info , method_info |
45.3 |
Deprecated |
ClassFile , field_info , method_info |
45.3 |
Signature |
ClassFile , field_info , method_info |
49.0 |
RuntimeVisibleAnnotations , RuntimeInvisibleAnnotations |
ClassFile , field_info , method_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 |
52.0 |
NestHost
AttributeThe NestHost
attribute is a fixed-length attribute in the attributes
table of a ClassFile
structure (4.1).
A nest is a set of classes and interfaces that share access to their private
members (5.4.4).
A class or interface with a NestHost
attribute belongs to the nest hosted by a designated host class. The host class authorizes membership in the nest with a corresponding entry in its NestMembers
attribute (4.7.29).
A class or interface without a NestHost
attribute belongs to the nest hosted by itself. If the class or interface also lacks a NestMembers
attribute, this nest is a singleton consisting only of the class or interface itself.
There may be at most one NestHost
attribute in the attributes
table of a ClassFile
structure.
The NestHost
attribute has 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 must be a valid index into the constant_pool
table. The constant_pool
entry at that index must be a CONSTANT_Utf8_info
structure (4.4.7) representing the string "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 the constant_pool
table. The constant_pool
entry at that index must be a CONSTANT_Class_info
structure (4.4.1) representing a class or interface.
If the referenced class cannot be loaded, does not belong to the same run-time package, or does not authorize nest membership, an error may occur during access checking (5.4.4).
NestMembers
AttributeThe NestMembers
attribute is a variable-length attribute in the attributes
table of a ClassFile
structure (4.1). It authorizes an enumerated set of classes and interfaces to claim membership in a nest hosted by the current class or interface.
There may be at most one NestMembers
attribute in the attributes
table of a ClassFile
structure.
The attributes
table of a ClassFile
structure must not contain both a NestHost
attribute and a NestMembers
attribute.
This rule prevents a host class from claiming membership in a different nest. It is implicitly a member of the nest that it hosts.
The NestMembers
attribute has 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 must be a valid index into the constant_pool
table. The constant_pool
entry at that index must be a CONSTANT_Utf8_info
structure (4.4.7) representing the string "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 indicates the number of entries in the classes array.
classes[]
Each value in the classes
array must be a valid index into the constant_pool
table. The constant_pool
entry at that index must be a CONSTANT_Class_info
structure (4.4.1) representing a class or interface.
This array is consulted during access checking (5.4.4). It should consist of references to other classes and interfaces that belong to the same run-time package and have
NestHost
attributes referencing this class or interface. Items that do not meet this description are discouraged and will be ignored by access checking.
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 also imposes loading constraints (5.3.4). Let L1 be the defining loader of C. For each instance method m declared in C that overrides can override (5.4.5) a an instance method declared in a superclass or superinterface <D, L2>, the Java Virtual Machine imposes the following loading constraints:
Given that the return type of m is Tr, and that the formal parameter types of m are Tf1, ..., Tfn, then:
If Tr not an array type, let T0 be Tr; otherwise, let T0 be the element type (2.4) of Tr.
For i = 1 to n: If Tfi is not an array type, let Ti be Tfi; otherwise, let Ti be the element type (2.4) of Tfi.
Then Ti^L1 = Ti^L2 for i = 0 to n.
Furthermore, if C implements a for each instance method m declared in a superinterface <I, L3> of C, but if C does not itself declare the method an instance method that can override m, then let <D, L2> be the superclass of C that declares the implementation of method m inherited by C. The if the selected method (5.4.5) for class or interface C of an invocation of m is declared in a class or interface <D, L2>, the Java Virtual Machine imposes the following constraints:
Given that the return type of m is Tr, and that the formal parameter types of m are Tf1, ..., Tfn, then:
If Tr not an array type, let T0 be Tr; otherwise, let T0 be the element type (2.4) of Tr.
For i = 1 to n: If Tfi is not an array type, let Ti be Tfi; otherwise, let Ti be the element type (2.4) of Tfi.
Then Ti^L2 = Ti^L3 for i = 0 to n.
Preparation may occur at any time following creation but must be completed prior to initialization.
These changes adopt the terminology of the modified 5.4.5 to more precisely define when loader constraints are introduced. It addresses JDK-8078636, which notes that "inherited" is undefined.
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.
If C is an array class and its element type is a reference type, then a symbolic reference to the class or interface representing the element type is resolved by invoking the algorithm in 5.4.3.1 recursively.
Finally, access permissions to C are checked (5.4.4).
If C is not accessible (5.4.4) to D, class or interface resolution throws an IllegalAccessError
.
This condition can occur, for example, if C is a class that was originally declared to be public
but was changed to be non-public
after D was compiled.
If steps 1 and 2 succeed but step 3 fails, C is still valid and usable. Nevertheless, resolution fails, and D is prohibited from accessing C.
To resolve an unresolved symbolic reference from D to a field in a class or interface C, the symbolic reference to C given by the field reference must first be resolved (5.4.3.1). Therefore, any exception that can be thrown as a result of failure of resolution of a class or interface reference can be thrown as a result of failure of field resolution. If the reference to C can be successfully resolved, an exception relating to the failure of resolution of the field reference itself can be thrown.
When resolving a field reference, field resolution first attempts to look up the referenced field in C and its superclasses:
If C declares a field with the name and descriptor specified by the field reference, field lookup succeeds. The declared field is the result of the field lookup.
Otherwise, field lookup is applied recursively to the direct superinterfaces of the specified class or interface C.
Otherwise, if C has a superclass S, field lookup is applied recursively to S.
Otherwise, field lookup fails.
Then:
If field lookup fails, field resolution throws a NoSuchFieldError
.
Otherwise, if field lookup succeeds but the referenced field is not accessible (5.4.4) to D, field resolution throws an If field lookup succeeds, access permissions to the referenced field are checked (5.4.4).IllegalAccessError
.
Otherwise If field lookup and access checking succeed, let <E, L1> be the class or interface in which the referenced field is actually declared and let L2 be the defining loader of D.
Given that the type of the referenced field is Tf, let T be Tf if Tf is not an array type, and let T be the element type (2.4) of Tf otherwise.
The Java Virtual Machine must impose the loading constraint that T^L1 = T^L2 (5.3.4).
To resolve an unresolved symbolic reference from D to a method in a class C, the symbolic reference to C given by the method reference is first resolved (5.4.3.1). Therefore, any exception that can be thrown as a result of failure of resolution of a class reference can be thrown as a result of failure of method resolution. If the reference to C can be successfully resolved, exceptions relating to the resolution of the method reference itself can be thrown.
When resolving a method reference:
If C is an interface, method resolution throws an IncompatibleClassChangeError
.
Otherwise, method resolution attempts to locate the referenced method in C and its superclasses: ...
Otherwise, method resolution attempts to locate the referenced method in the superinterfaces of the specified class C: ...
A maximally-specific superinterface method of a class or interface C for a particular method name and descriptor is any method for which all of the following are true: ...
The result of method resolution is determined by whether method lookup succeeds or fails:
If method lookup fails, method resolution throws a NoSuchMethodError
.
Otherwise, if method lookup succeeds and the referenced method is not accessible (5.4.4) to D, method resolution throws an If method lookup succeeds, access permissions to the referenced method are checked (5.4.4).IllegalAccessError
.
Otherwise If method lookup and access checking succeed, let <E,L1> be the class or interface in which the referenced method m is actually declared, and let L2 be the defining loader of D. ...
...
To resolve an unresolved symbolic reference from D to an interface method in an interface C, the symbolic reference to C given by the interface method reference is first resolved (5.4.3.1). Therefore, any exception that can be thrown as a result of failure of resolution of an interface reference can be thrown as a result of failure of interface method resolution. If the reference to C can be successfully resolved, exceptions relating to the resolution of the interface method reference itself can be thrown.
When resolving an interface method reference:
If C is not an interface, interface method resolution throws an IncompatibleClassChangeError
.
Otherwise, if C declares a method with the name and descriptor specified by the interface method reference, method lookup succeeds.
Otherwise, if the class Object
declares a method with the name and descriptor specified by the interface method reference, which has its ACC_PUBLIC
flag set and does not have its ACC_STATIC
flag set, method lookup succeeds.
Otherwise, if the maximally-specific superinterface methods (5.4.3.3) of C for the name and descriptor specified by the method reference include exactly one method that does not have its ACC_ABSTRACT
flag set, then this method is chosen and method lookup succeeds.
Otherwise, if any superinterface of C declares a method with the name and descriptor specified by the method reference that has neither its ACC_PRIVATE
flag nor its ACC_STATIC
flag set, one of these is arbitrarily chosen and method lookup succeeds.
Otherwise, method lookup fails.
The result of interface method resolution is determined by whether method lookup succeeds or fails:
If method lookup fails, interface method resolution throws a NoSuchMethodError
.
If method lookup succeeds and the referenced method is not accessible (5.4.4) to D, interface method resolution throws an If method lookup succeeds, access permissions to the referenced method are checked (5.4.4).IllegalAccessError
.
Otherwise If method lookup and access checking succeed, let <E,L1> be the class or interface in which the referenced method m is actually declared, and let L2 be the defining loader of D. ...
...
...
To resolve MH, all symbolic references to classes, interfaces, fields, and methods in MH's bytecode behavior are resolved, using the following four steps:
First, 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
.
Second, 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 8
(REF_newInvokeSpecial
), then R must resolve to an instance initialization method declared in class C.
If MH's bytecode behavior is kind 9
(REF_invokeInterface
), then R must resolve to a non-private
method.
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
, and REF_invokeVirtual
): If C.f or C.m resolved to a protected
field or method, and C is in a different run-time package than the current class, then C must be assignable to the current class.
For kind 8
(REF_newInvokeSpecial
): If C.<init>
resolved to a protected
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
, and REF_invokeInterface
): C.f or C.m must resolve to a non-static
field or method.
For kinds 2
, 4
, and 6
(REF_getStatic
, REF_putStatic
, and REF_invokeStatic
): C.f or C.m must resolve to a static
field or method.
Third, resolution occurs as if of unresolved symbolic references to classes and interfaces whose names correspond to each type in A*, and to the type T, in that order.
Fourth, 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, 3, and 4, any exception that can be thrown as a result of failure of resolution of a symbolic reference to a class, interface, field, or method 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.
...
Access checking is performed during resolution to ensure that a reference is permitted to a class, interface, field, or method.
This section has been modified slightly to describe a set of errors that may occur during "access checking", rather than merely defining a simple boolean "is accessible" predicate. This is because class resolution now occurs during access checking, producing other sorts of errors (such as NoClassDefFoundError
).
A class or interface C is accessible to a class or interface D if and only if one of the following is true:
C is public
, and a member of the same run-time module as D (5.3.6).
C is public
, and a member of a different run-time module than D, and C's run-time module is read by D's run-time module, and C's run-time module exports C's run-time package to D's run-time module.
C is not public
, and C and D are members of the same run-time package.
If a referenced class or interface is not accessible, access checking throws an IllegalAccessError
.
A field or method R is accessible to a class or interface D if and only if any of the following is true:
R is public
.
R is protected
and is declared in a class C, and D is either a subclass of C or C itself. Furthermore, if R is not static
, then the symbolic reference to R must contain a symbolic reference to a class T, such that T is either a subclass of D, a superclass of D, or D itself.
During verification, it was also required that, even if T is a superclass of D, the target reference of a
protected
instance field access or method invocation must be an instance of D or a subclass of D (4.10.1.8).
R is either protected
or has default access (that is, neither public
nor protected
nor private
), and is declared by a class in the same run-time package as D.
R is private
and is declared in D by a class or interface belonging to the same nest as D.
If a referenced field or method is not accessible, access checking throws an IllegalAccessError
. If an exception is thrown while attempting to determine the nest host of a class or interface, access checking fails for the same reason.
If wanted, the following material could be separated into a subsection or moved to some other part of JVMS.
To determine whether a class or interface C belongs to the same nest as D, the following steps are performed:
If C and D are the same class or interface, they belong to the same nest.
Otherwise, the nest host of D, H, is determined. If an exception is thrown, the nest membership test fails for the same reason.
Otherwise, the nest host of C, H', is determined. If an exception is thrown, the nest membership test fails for the same reason.
Otherwise, C and D belong to the same nest if H and H' are the same class or interface.
To determine the nest host of a class M, the following steps are performed:
If M lacks a NestHost
attribute (4.7.28), M is its own nest host.
Otherwise, where i is the host_class_index
item of M's NestHost
attribute, the symbolic reference at index i of M's run-time constant pool is resolved to a class or interface H (5.4.3.1). Any of the exceptions pertaining to class or interface resolution can be thrown.
If resolution of H succeeds, but H is not declared in the same run-time package as M, an IncompatibleClassChangeError
is thrown.
Otherwise, if H lacks a NestMembers
attribute (4.7.29), or if, where M has name N, there exists no entry in the classes
array of the NestMembers
attribute of H that refers to a class or interface with name N, an IncompatibleClassChangeError
is thrown.
Otherwise, H is the nest host of M.
This discussion of access control omits a related restriction on the target of a protected
field access or method invocation (the target must be of class D or a subtype of D). That requirement is checked as part of the verification process (4.10.1.8); it is not part of link-time access control.
Note that entries in the NestMembers
attribute are left unresolved. Simply looking for the candidate member's name is sufficient, because the candidate member is known to belong to the same run-time package.
A future enhancement may allow classes to be declared private
, accessible only to nestmates. If that occurs, the steps to determine the nest host will have to change slightly, because there would be a circular dependency: nest host determination depends on class resolution, class resolution depends on class access checking, and class access checking depends on nest host resolution.
In order to support invocation of private
methods with invokeinterface
, we need to modify the invokeinterface
selection rules (otherwise, some unwanted private
methods would be selected and invoked). Rather than creating a new set of rules, this section is modified to be general enough to handle class-interface and interface-interface overriding. It also includes the closely-related method selection algorithm, avoiding the need to repeat it in two different places.
An instance method mC declared in class C overrides can override another instance method mA declared in class A iff either mC is the same as mA, or all of the following are true:
C is a subclass of A.
mC has the same name and descriptor as mA.
mC is not marked ACC_PRIVATE
.
ACC_PUBLIC
ACC_PROTECTED
ACC_PUBLIC
nor ACC_PROTECTED
nor ACC_PRIVATE
, and ACC_PUBLIC
nor ACC_PROTECTED
nor ACC_PRIVATE
, and, where mC is declared in a class C and mA is declared in a class A, there exists a method mB declared in a class B, such that C is a subclass of B, B is a subclass of A, mC can override mB, and mB can override mA.This definition no longer attempts to constrain the relationship between C and A (e.g., if C is a class and A is an interface, C need not implement A, which is important if some subclass of C implements A). Instead, the definition is renamed "can override", and it's up to the client (e.g., the selection algorithm below) to ensure that C and A have an acceptable relationship.
This definition is also no longer reflexive for private
methods. (Reflexivity for other methods falls out from the other rules.) Given the special treatment of private
methods during selection (below), there are no clients that rely on reflexivity of private
methods, and it's a little unnatural to talk about methods that "override" themselves.
The final case allows for "transitive overriding" of methods with default access. For example, given the following class declarations in a package
p1
:
public class A { void m() {} } public class B extends A { public void m() {} } public class C extends B { void m() {} }
And the following class declaration in a package
p2
:
public class D extends p1.C { void m() {} }
Then:
B.m
can overrideA.m
.C.m
can overrideB.m
andA.m
.D.m
can overrideB.m
and, transitively,A.m
, but notC.m
.
If wanted, the following material could be separated into a subsection or moved to some other part of JVMS.
Where an invokevirtual
or an invokeinterface
invocation refers to a resolved method mR, the selected method of the invocation for an instance of a class or interface C is determined as follows:
If mR is marked ACC_PRIVATE
, then it is the selected method.
Otherwise, the selected method is determined by the following lookup procedure:
If C contains a declaration for an instance method m that can override the resolved method, then m is the selected method.
Otherwise, if C has a superclass, a search for a declaration of an instance method that can override the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a method is found or no further superclasses exist. If a method is found, it is the selected method.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract
, then it is the selected method.
Note that any maximally-specific method selected in this step can override mR; there is no need to check this explicitly.
While C will typically be a class, it may be an interface when these rules are applied during preparation (5.4.2).
Beyond improving presentation, this change has the following effects:
Addresses JDK-8098577: if an invokevirtual
resolves to an interface method, C or one of its superclasses may override the interface method.
private
methods from being selected by invokeinterface
, unless the private
method is also the referenced method.invokeinterface
...
...
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: The selected method (5.4.5) for class C of an invocation of the referenced method is the actual method to be invoked.
If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.
Otherwise, if C has a superclass, a search for a declaration of an instance method with the same name and descriptor as the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a match is found or no further superclasses exist. If a match is found, then it is the method to be invoked.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract
, then it is the method to be invoked.
...
During resolution of the symbolic reference to the interface method, any of the exceptions pertaining to interface method resolution (5.4.3.4) can be thrown.
Otherwise, if the resolved method is static
or , the private
invokeinterface
instruction throws an IncompatibleClassChangeError
.
This change allows invokeinterface
to refer to private
methods declared in interfaces, including nestmate interfaces.
Otherwise, if objectref is null
, the invokeinterface
instruction throws a NullPointerException
.
Otherwise, if the class of objectref does not implement the resolved interface, invokeinterface
throws an IncompatibleClassChangeError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects a method that is not public
, invokeinterface
throws an IllegalAccessError
.
This addresses JDK-8024806: invokeinterface
may select a non-public
method without error, aligning it with invokevirtual
.
Otherwise, if step 1 or step 2 of the lookup procedure selects the selected method is an abstract
method, invokeinterface
throws an AbstractMethodError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects the selected method is a native
method and the code that implements the method cannot be bound, invokeinterface
throws an UnsatisfiedLinkError
.
Otherwise, if no selected method can be found and step 3 of the lookup procedure determines there are multiple maximally-specific methods in the superinterfaces of C that match the resolved method's name and descriptor and are not abstract
, invokeinterface
throws an IncompatibleClassChangeError
.
Otherwise, if no selected method can be found and step 3 of the lookup procedure determines there are zero maximally-specific methods in the superinterfaces of C that match the resolved method's name and descriptor and are not abstract
, invokeinterface
throws an AbstractMethodError
.
...
invokespecial
Invoke instance method; special handling for superclass, private, and instance initialization method invocations direct invocation of instance initialization methods and methods of the current class and its supertypes
...
The difference between the invokespecial
instruction and the invokevirtual
instruction (invokevirtual
) is that invokevirtual
invokes a method based on the class of the object. The invokespecial
instruction is used to directly invoke instance initialization methods (2.9.1) as well as methods of the current class and its supertypes.private
methods and methods of a superclass of the current class
The
invokespecial
instruction was namedinvokenonvirtual
prior to JDK release 1.0.2.
The nargs argument values and objectref are not one-to-one with the first nargs+1 local variables. Argument values of types long
and double
must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.
The invokespecial
instruction handles invocation of a a non-private
interface method,abstract
interface method, referenced either via a direct superinterface, and a non- or a superclass. In these cases, the rules for selection are essentially the same as those for abstract
interface method referenced viainvokeinterface
(except that the search starts from a different class).
invokevirtual
...
...
If the resolved method is not signature polymorphic (2.9), then the invokevirtual
instruction proceeds as follows.
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: The selected method (5.4.5) for class C of an invocation of the referenced method is the actual method to be invoked.
If C contains a declaration for an instance method m that overrides (5.4.5) the resolved method, then m is the method to be invoked.
Otherwise, if C has a superclass, a search for a declaration of an instance method that overrides the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until an overriding method is found or no further superclasses exist. If an overriding method is found, it is the method to be invoked.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract
, then it is the method to be invoked.
...
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (5.4.3.3) can be thrown.
Otherwise, if the resolved method is a class (static
) method, the invokevirtual
instruction throws an IncompatibleClassChangeError
.
Otherwise, if the resolved method is signature polymorphic, then during resolution of the method type derived from the descriptor in the symbolic reference to the method, any of the exceptions pertaining to method type resolution ([5.4.3.5]) can be thrown.
Otherwise, if objectref is null
, the invokevirtual
instruction throws a NullPointerException
.
Otherwise, if the resolved method is a protected
method of a superclass of the current class, declared in a different run-time package, and the class of objectref is not the current class or a subclass of the current class, then invokevirtual
throws an IllegalAccessError
.
Otherwise, if the resolved method is not signature polymorphic:
If step 1 or step 2 of the lookup procedure selects the selected method is an abstract
method, invokevirtual
throws an AbstractMethodError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects the selected method is a native
method and the code that implements the method cannot be bound, invokevirtual
throws an UnsatisfiedLinkError
.
Otherwise, if no selected method can be found and step 3 of the lookup procedure determines there are multiple maximally-specific methods in the superinterfaces of C that match the resolved method's name and descriptor and are not abstract
, invokevirtual
throws an IncompatibleClassChangeError
Otherwise, if no selected method can be found and step 3 of the lookup procedure determines there are zero maximally-specific methods in the superinterfaces of C that match the resolved method's name and descriptor and are not abstract
, invokevirtual
throws an AbstractMethodError
.
Otherwise, if the resolved method is signature polymorphic, then:
If the method name is invokeExact
, and the obtained instance of java.lang.invoke.MethodType
is not semantically equal to the type descriptor of the receiving method handle, the invokevirtual
instruction throws a java.lang.invoke.WrongMethodTypeException
.
If the method name is invoke
, and the obtained instance of java.lang.invoke.MethodType
is not a valid argument to the java.lang.invoke.MethodHandle.asType
method invoked on the receiving method handle, the invokevirtual
instruction throws a java.lang.invoke.WrongMethodTypeException
.
...
Copyright © 2017 Oracle America, Inc. 4150 Network Circle, Santa Clara, California 95054, U.S.A. All rights reserved.
The Specification is protected by copyright and the information described therein may be protected by one or more U.S. patents, foreign patents, or pending applications. Except as provided under the following license, no part of the Specification may be reproduced in any form by any means without the prior written authorization of Oracle America, Inc. ("Oracle") and its licensors, if any. Any use of the Specification and the information described therein will be governed by the terms and conditions of this Agreement.
Subject to the terms and conditions of this license, including your compliance with Paragraphs 1 and 2 below, Oracle hereby grants you a fully-paid, non-exclusive, non-transferable, limited license (without the right to sublicense) under Oracle's intellectual property rights to:
Review the Specification for the purposes of evaluation. This includes: (i) developing implementations of the Specification for your internal, non-commercial use; (ii) discussing the Specification with any third party; and (iii) excerpting brief portions of the Specification in oral or written communications which discuss the Specification provided that such excerpts do not in the aggregate constitute a significant portion of the Technology.
Distribute implementations of the Specification to third parties for their testing and evaluation use, provided that any such implementation:
does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other than those required/authorized by the Specification or Specifications being implemented;
is clearly and prominently marked with the word "UNTESTED" or "EARLY ACCESS" or "INCOMPATIBLE" or "UNSTABLE" or "BETA" in any list of available builds and in proximity to every link initiating its download, where the list or link is under Licensee's control; and
includes the following notice: "This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and is made available for testing and evaluation purposes only. The code is not compatible with any specification of the JCP."
The grant set forth above concerning your distribution of implementations of the specification is contingent upon your agreement to terminate development and distribution of your "early draft" implementation as soon as feasible following final completion of the specification. If you fail to do so, the foregoing grant shall be considered null and void.
No provision of this Agreement shall be understood to restrict your ability to make and distribute to third parties applications written to the Specification.
Other than this limited license, you acquire no right, title or interest in or to the Specification or any other Oracle intellectual property, and the Specification may only be used in accordance with the license terms set forth herein. This license will expire on the earlier of: (a) two (2) years from the date of Release listed above; (b) the date on which the final version of the Specification is publicly released; or (c) the date on which the Java Specification Request (JSR) to which the Specification corresponds is withdrawn. In addition, this license will terminate immediately without notice from Oracle if you fail to comply with any provision of this license. Upon termination, you must cease use of or destroy the Specification.
"Licensor Name Space" means the public class or interface declarations whose names begin with "java", "javax", "com.oracle" or their equivalents in any subsequent naming convention adopted by Oracle through the Java Community Process, or any recognized successors or replacements thereof.
No right, title, or interest in or to any trademarks, service marks, or trade names of Oracle or Oracle's licensors is granted hereunder. Oracle, the Oracle logo, Java are trademarks or registered trademarks of Oracle USA, Inc. in the U.S. and other countries.
THE SPECIFICATION IS PROVIDED "AS IS" AND IS EXPERIMENTAL AND MAY CONTAIN DEFECTS OR DEFICIENCIES WHICH CANNOT OR WILL NOT BE CORRECTED BY ORACLE. ORACLE MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of the Specification in any product.
THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. ORACLE MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification.
TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ORACLE OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF THE SPECIFICATION, EVEN IF ORACLE AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
You will hold Oracle (and its licensors) harmless from any claims based on your use of the Specification for any purposes other than the limited right of evaluation as described above, and from any claims that later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license.
If this Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Software and accompanying documentation shall be only as set forth in this license; this is in accordance with 48 C.F.R. 227.7201 through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
You may wish to report any ambiguities, inconsistencies or inaccuracies you may find in connection with your evaluation of the Specification ("Feedback"). To the extent that you provide Oracle with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, and (ii) grant Oracle a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any purpose related to the Specification and future versions, implementations, and test suites thereof.
Any action related to this Agreement will be governed by California law and controlling U.S. federal law. The U.N. Convention for the International Sale of Goods and the choice of law rules of any jurisdiction will not apply.
The Specification is subject to U.S. export control laws and may be subject to export or import regulations in other countries. Licensee agrees to comply strictly with all such laws and regulations and acknowledges that it has the responsibility to obtain such licenses to export, re-export or import as may be required after delivery to Licensee.
This Agreement is the parties' entire agreement relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, conditions, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification to this Agreement will be binding, unless in writing and signed by an authorized representative of each party.