Navigation: Overview - Part A - Part B - Part C - Part D - Part E - Part F - Part G - Part H - Part J
Sections: JVMS-4.6 - JVMS-4.9.1 - JVMS-4.9.2 - JVMS-4.4.8 - JVMS-5.4.3.3 - JVMS-5.4.3.4 - JVMS-5.4.5 - JVMS-6.5.invokeinterface - JVMS-6.5.invokespecial - JVMS-6.5.invokestatic - JVMS-6.5.invokevirtual
Version 0.9.3. Copyright © 2014 Oracle America, Inc. Legal Notice.
Changes to the Java Virtual Machine are necessary to support the implementation of default methods. Methods declared in interface class files need not be declared abstract, and thus can carry a Code attribute. Methods declared in interface class files may also be private or static. The invokespecial and invokestatic instructions may refer to interface methods. The rules for method resolution and invocation (via invokeinterface, invokespecial, invokestatic, and invokevirtual) are enhanced to support execution of code in interfaces.
Compare JVMS 4.6
...
Methods of classes may set any of the flags in Table 4.5. However, a specific method of a class may have at most one of its ACC_PRIVATE, ACC_PROTECTED, and ACC_PUBLIC flags set (8.4.3). [jvms-4.6-200-A.5]
Methods of interfaces may set any of the flags in Table 4.5 except ACC_PROTECTED, ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED (9.4); they must have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set. [jsr335-4.6-200-A.10]
An interface method in a class file whose version number is not 52.0 or above must have its ACC_ABSTRACT and ACC_PUBLIC flags set they may have their . [jvms-4.6-200-A.6]
ACC_VARARGS, ACC_BRIDGE, and ACC_SYNTHETIC flags set and must not have any of the other flags in Table 4.5 set (9.4)
If a specific method of a class or interface has its ACC_ABSTRACT flag set, it must not have any of its ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, ACC_STRICT, or ACC_SYNCHRONIZED flags set (8.4.3.1, 8.4.3.3, 8.4.3.4). [jsr335-4.6-200-A.11]
...
Discussion and motivation:
Interface methods prior to version 52.0 must beabstract, and thus must not beprivate,static, orstrictfp; they are also prohibited from havingCodeattributes (4.7.3). In version 52.0, an interface method may be non-abstract and thus is free to use these flags and have aCodeattribute.
Compare JVMS 4.9.1
...
The static constraints on the operands of instructions in the code array are as follows: [jvms-4.9.1-120]
...
invokevirtual invokespecial, and invokestaticconstant_pool table. The constant pool entry referenced by that index must be of type CONSTANT_Methodref. [jvms-4.9.1-120-G]
invokespecial and invokestatic instruction must represent a valid index into the constant_pool table. The constant pool entry referenced by that index must be either of type CONSTANT_Methodref or, if the constant pool appears in a class file whose version number is 52.0 or above, of type CONSTANT_InterfaceMethodref. [jsr335-4.9.1-120-T]
...
Discussion and motivation:
In order to invokestaticandprivatemethods in interfaces,InterfaceMethodrefsmust be supported by theinvokestaticandinvokespecialinstructions. In addition, this change allows non-static, non-abstractmethods appearing in a direct superinterface to be invoked viainvokespecial.
Compare JVMS 4.9.2
The structural constraints on the code array specify constraints on relationships between Java virtual machine instructions. The structural constraints are as follows: [jvms-4.9.2-100]
...
invokespecial instruction must name an instance initialization method (2.9), or must reference a method in the current class or interface, If an invokespecial instruction names an instance initialization method from referenced in a class that is not the current class or a superclass, 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 referenced in the class of that class instance. [jvms-4.9.2-120-G.2]
...
Discussion and motivation:
A clause is added to supportinvokespecialof default methods in a superinterface. References to a superinterface method must point to a direct superinterface; this is in contrast to references to a superclass method, which can point to any superclass. This is because i) the search path for a closer match of an interface method (as required by theACC_SUPERflag) is not clear if the reference is not to a direct superinterface, and ii) there is no practical need for more flexibility (note that a reference can resolve to a method in an ancestor interface, even if the interface is not named directly). In retrospect, the ideal probably would have been to make a similar restriction on invocations of superclass methods. The introduction of phrases like "referenced in" is a clarification of existing behavior: the check is against the class appearing in theMethodreforInterfaceMethodref, not the declaring class of the resolved method.
CONSTANT_MethodHandle_info Structure [Modified] Compare JVMS 4.4.8
...
If the value of the reference_kind item is 5 (REF_invokeVirtual) 6 ( or 8 (REF_invokeStatic), 7 (REF_invokeSpecial),REF_newInvokeSpecial), then the constant_pool entry at that index must be a CONSTANT_Methodref_info (4.4.2) structure representing a class's method or constructor (2.9) for which a method handle is to be created. [jvms-4.4.8-200-C.2]
If the value of the reference_kind item is 6 (REF_invokeStatic) or 7 (REF_invokeSpecial), then the constant_pool entry at that index must be either a CONSTANT_Methodref_info structure or, if the constant pool appears in a class file whose version number is 52.0 or above, a CONSTANT_InterfaceMethodref (4.4.2) structure representing a class's or interface's method for which a method handle is to be created. [jsr335-4.4.8-200-C.6]
If the value of the reference_kind item is 9 (REF_invokeInterface), then the constant_pool entry at that index must be a CONSTANT_InterfaceMethodref_info (4.4.2) structure representing an interface's method for which a method handle is to be created. [jsr335-4.4.8-200-C.3]
...
Compare JVMS 5.4.3.3
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 method resolution. If the reference to C can be successfully resolved, exceptions relating to the resolution of the method reference itself can be thrown. [jvms-5.4.3.3-100]
When resolving a method reference: [jvms-5.4.3.3-200]
IncompatibleClassChangeError. [jvms-5.4.3.3-200-A-1]
ACC_ABSTRACT flag, then this method is chosen and method lookup succeeds. [jsr335-5.4.3.3-200-C-3]
ACC_PRIVATE flag nor its ACC_STATIC flag, one of these is arbitrarily chosen and method lookup succeeds. [jvms-5.4.3.3-200-C-1]
A maximally-specific superinterface method of a class or interface C for a particular method name and descriptor is any method for which the following conditions hold: [jsr335-5.4.3.3-25]
ACC_PRIVATE flag nor its ACC_STATIC flag. [jsr335-5.4.3.3-25-C]
If method lookup fails, method resolution throws a NoSuchMethodError. [jvms-5.4.3.3-210-A]
If method lookup succeeds and the method is [jvms-5.4.3.3-210-B]
abstract, but C is not abstract, method resolution throws an AbstractMethodError.
Otherwise, if If method lookup succeeds and the referenced method is not accessible (5.4.4) to D, method resolution throws an IllegalAccessError. [jvms-5.4.3.3-210-C]
...
Discussion and motivation:
When resolution searches for a method in the class's superinterfaces, we prefer to identify a maximally-specific non-abstract method. This is because it is possible that this is the method that will be selected and invoked by aninvokeinstruction, and so we want to ensure that class loader constraints are performed for this method.Otherwise, the result is nondeterministic. This is not new: the specification has never identified exactly which method is chosen, and how "ties" should be broken. In the past, this was mostly an unobservable distinction. However, now that the set of interface methods is more heterogenous, care must be taken to avoid more serious problems with nondeterministic behavior.
Thus:
- Superinterface methods that are
privateandstaticare ignored by resolution. This is consistent with the Java language view of these declarations, which says that they are not inherited. They can still be referenced, of course, by directly naming the interface in which they are declared, via anInterfaceMethodref. (In retrospect, it might be more consistent with the Java language to give the same treatment to private methods in classes...)- Any behavior controlled by the resolved method should not depend on whether the method is
abstractor not. The check that the resolved method is notabstractunless the named class is alsoabstracthas been removed. This is a rather ad hoc check, and conflicts with the nondeterministic choice of interface methods, as explained above. The effect of removing the check is to allowabstractmethods in non-abstractclasses to be invoked, assuming that the object for the invocation has a concrete implementation of the method.This change is retroactive for all class versions.
Compare JVMS 5.4.3.4
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 interface method resolution. If the reference to C can be successfully resolved, exceptions relating to the resolution of the method reference itself can be thrown. [jvms-5.4.3.4-100]
When resolving an interface method reference: [jvms-5.4.3.4-200]
IncompatibleClassChangeError. [jvms-5.4.3.4-200-A]
Object declares a method with the name and descriptor specified by the interface method reference that has set its ACC_PUBLIC flag and does not have set its ACC_STATIC flag, method lookup succeeds. [jsr335-5.4.3.4-200-E]
ACC_ABSTRACT flag, then this method is chosen and method lookup succeeds. [jsr335-5.4.3.4-200-F]
ACC_PRIVATE flag nor its ACC_STATIC flag, one of these is arbitrarily chosen and method lookup succeeds. [jsr335-5.4.3.4-200-G]
NoSuchMethodError. [jsr335-5.4.3.4-200-H]
If method lookup succeeds and the referenced method is not accessible (5.4.4) to D, method resolution throws an IllegalAccessError. [jsr335-5.4.3.4-210]
...
Discussion and motivation:
The clause about access is added because resolution may pick aprivatemethod of interface C. An oversight in previous iterations of the JVM Specification allowed non-public and static methods of the classObjectto be the result of interface method resolution. Such results were not consistent with the Java language's inheritance model (see 9.2), nor were they properly handled downstream (such as in the specification forinvokeinterface). This is corrected by disallowing resolution to such methods.
Compare JVMS 5.4.5
An instance method m1 declared in a class C overrides another instance method m2 declared in a class A iff either m1 is the same as m2, or all of the following are true: [jvms-5.4.5-100]
ACC_PRIVATE. [jsr335-5.4.5-100-D]
ACC_PUBLIC; or is marked ACC_PROTECTED; or is marked neither ACC_PUBLIC nor ACC_PROTECTED nor ACC_PRIVATE and belongs to the same run-time package as C, or [jvms-5.4.5-100-C-A]
Discussion and motivation:
This is a bug fix to make the specification consistent with longstanding VM behavior, which is to skip over private methods during selection. (It also clarifies that private methods can be considered to "override" themselves.)
Compare JVMS 6.5.invokeinterface
...
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: [jvms-6.5.invokeinterface.desc-200]
abstract, this is the method to be invoked. [jsr335-6.5.invokeinterface.desc-200-D3]
abstract, an IncompatibleClassChangeError is raised. [jsr335-6.5.invokeinterface.desc-200-D4]
AbstractMethodError is raised. [jvms-6.5.invokeinterface.desc-200-C]
...
During resolution of the symbolic reference to the interface method, any of the exceptions pertaining to interface method resolution (JVMS-5.4.3.4) can be thrown. [jvms-6.5.invokeinterface.linking-100]
Otherwise, if the resolved method is a static method, the invokeinterface instruction throws an IncompatibleClassChangeError. [jsr335-6.5.invokeinterface.linking-20]
Otherwise, if the resolved method is a private method, the invokeinterface instruction throws an IncompatibleClassChangeError. [jsr335-6.5.invokeinterface.linking-22]
Otherwise, if objectref is null, the invokeinterface instruction throws a NullPointerException. [jsr335-6.5.invokeinterface.runtime-100]
Otherwise, if the class of objectref does not implement the resolved interface, invokeinterface throws an IncompatibleClassChangeError. [jsr335-6.5.invokeinterface.runtime-110]
Otherwise, if no method matching the resolved name and descriptor is selected,
invokeinterface throws an AbstractMethodError. [jsr335-6.5.invokeinterface.runtime-120]
Otherwise, if the selected method is not public, invokeinterface throws an IllegalAccessError. [jsr335-6.5.invokeinterface.runtime-130]
Otherwise, if the selected method is abstract, invokeinterface throws an AbstractMethodError. [jsr335-6.5.invokeinterface.runtime-140]
Otherwise, if the selected method is native ... [jsr335-6.5.invokeinterface.runtime-150]
Discussion and motivation:
The selection logic is modified so that a non-abstractmethod declared in a superinterface may be selected. By design, this change is retroactive: aninvokeinterfaceoccurring in an old class file may have the effect of invoking a non-abstractinterface method declared in a new class file.Methods in interfaces are only considered if there is no matching method in the class hierarchy.
In the event that we must choose between two non-
abstractmethods in the superinterface hierarchy, with neither more specific than the other, an error occurs. We do not attempt to disambiguate (for example, one may be the referenced method and one may be unrelated, but we do not prefer the referenced method).On the other hand, if there are many
abstractmethods but only one non-abstractmethod, the non-abstractmethod is chosen (unless anabstractmethod is more specific).Like method resolution, method selection ignores
privateandstaticmethods declared in superinterfaces. Likeinvokevirtual,invokeinterfacedoes not allow the resolved method to bestatic(this was impossible in previous versions, assuming the classObjecthas nostaticmethods). Sinceprivateinterface methods cannot be selected, we similarly report an error if the resolved method isprivate. Given the restructured selection logic, it is no longer necessary to separately mandate anAbstractMethodErrorif nothing is found. So that clause has been removed (but the behavior in that case is unchanged).
Compare JVMS 6.5.invokespecial
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the runtime constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The runtime constant pool item at that index must be a symbolic reference to a method or an interface method (5.1), which gives the name and descriptor (4.3.3) of the method as well as a symbolic reference to the class or interface in which the method is to be found. The named method is resolved (5.4.3.3, 5.4.3.4). Finally, if the resolved method is protected (4.6), and it is a member of a superclass of the current class, and the method is not declared in the same runtime package (5.3) as the current class, then the class of objectref must be either the current class or a subclass of the current class, or an IllegalAccessError is raised. [jvms-6.5.invokespecial.desc-100]
Next, the resolved a method is selected for invocation according to the following rules. [jsr335-6.5.invokespecial.desc-150]
Let C be the class or interface named by the method reference or interface method reference, unless all of the following conditions are true: [jvms-6.5.invokespecial.desc-200]
ACC_SUPER flag (see Table 4.1, "Class access and property modifiers") is set for the current class. [jvms-6.5.invokespecial.desc-200-A]
If the above conditions are true, the actual method to be invoked is selected by the following lookup procedure let C, instead, be the direct superclass of the current class. [jsr335-6.5.invokespecial.desc-210]
The method for invocation is selected as follows: [jvms-6.5.invokespecial.desc-300]
Object contains a declaration of a public (4.6) instance method with the same name and descriptor as the resolved method, this is the method to be invoked. [jvms-6.5.invokespecial.desc-300-E]
abstract, this is the method to be invoked. [jsr335-6.5.invokespecial.desc-300-D3]
abstract, an IncompatibleClassChangeError is raised. [jsr335-6.5.invokespecial.desc-300-D4]
AbstractMethodError is raised. [jvms-6.5.invokespecial.desc-300-C]
...
Otherwise, if objectref is null, the invokespecial instruction throws a NullPointerException. [jvms-6.5.invokespecial.runtime-100]
Otherwise if no method matching the resolved name and descriptor is selected,
invokespecial throws an AbstractMethodError. [jvms-6.5.invokespecial.runtime-110]
Otherwise, if the selected method is abstract, invokespecial throws an AbstractMethodError. [jvms-6.5.invokespecial.runtime-120]
Otherwise, if the selected method is native ... [jvms-6.5.invokespecial.runtime-130]
Discussion and motivation:
Theinvokespecialinstruction is extended to:
- Handle invocation of a
privateinterface method.- Handle invocation of a non-
abstractinterface method referenced via a direct superinterface.- Handle invocation of a non-
abstractinterface method referenced via a superclass.In these cases, the rules for selection are essentially the same as those for
invokeinterface(except that the search starts from a different class).For simplicity of presentation, the selection logic has been changed to apply in all cases. Sometimes this is redundant—in fact, with the exception of the
ACC_SUPERtrick performed for indirect superclass invocations, if selection produces a method, it will be the resolved method. But, selection must also ensure that appropriate error checks (such as theIncompatibleClassChangeError) are performed, to avoid nondeterminism. The behavior of selection has been clarified slightly to account for the possibility that theMethodrefresolves to an interface method, but this method has a closer match in a superclass.public interface I { public abstract void m(); } public abstract class A implements I {} public class B extends A { public void m() { ... } } public class C extends B { public void test() { invokespecial A.m()V; } }The previous specification text suggested that this would be an
AbstractMethodError, since sinceIis not "a superclass of the current class". However, the behavior of the HotSpot VM here has been to selectB.m.
Compare JVMS 6.5.invokestatic
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the runtime constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The runtime constant pool item at that index must be a symbolic reference to a method or an interface method (5.1), which gives the name and descriptor (4.3.3) of the method as well as a symbolic reference to the class or interface in which the method is to be found. The named method is resolved (5.4.3.3). The resolved method must not be an instance initialization method (2.9) or the a class or interface initialization method (2.9). It must be static, and therefore cannot be abstract. [jvms-6.5.invokestatic.desc-100]
On successful resolution of the method, the class or interface that declared the resolved method is initialized (5.5) if that class or interface has not already been initialized. [jvms-6.5.invokestatic.desc-110]
...
Otherwise, if the resolved method is an instance method, the invokestatic instruction throws an IncompatibleClassChangeError. [jvms-6.5.invokestatic.linking-110]
Otherwise, if execution of this invokestatic instruction causes initialization of the referenced class or interface, invokestatic may throw an Error as detailed in 5.5. [jvms-6.5.invokestatic.runtime-100]
...
Discussion and motivation:
Theinvokestaticinstruction is extended to handle invocation of astaticinterface method.
Compare JVMS 6.5.invokevirtual
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the runtime constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The runtime constant pool item at that index must be a symbolic reference to a method (5.1), which gives the name and descriptor (4.3.3) of the method as well as a symbolic reference to the class in which the method is to be found. The named method is resolved (5.4.3.3). The resolved method must not be an instance initialization method (2.9) or the a class or interface initialization method (2.9). Finally, if the resolved method is protected (4.6), and it is a member of a superclass of the current class, and the method is not declared in the same runtime package (5.3) as the current class, then the class of objectref must be either the current class or a subclass of the current class. [jvms-6.5.invokevirtual.desc-100]
If the resolved method is not signature polymorphic (2.9), then the invokevirtual instruction proceeds as follows. [jvms-6.5.invokevirtual.desc-200]
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: [jvms-6.5.invokevirtual.desc-210]
abstract, this is the method to be invoked. [jsr335-6.5.invokevirtual.desc-210-D3]
abstract, an IncompatibleClassChangeError is raised. [jsr335-6.5.invokevirtual.desc-210-D4]
AbstractMethodError is raised. [jvms-6.5.invokevirtual.desc-210-C]
...
Otherwise, if the resolved method is not signature polymorphic: [jvms-6.5.invokevirtual.runtime-110]
invokevirtual throws an AbstractMethodError. [jvms-6.5.invokevirtual.runtime-110-A]abstract, invokevirtual throws an AbstractMethodError. [jvms-6.5.invokevirtual.runtime-110-B]
native ... [jvms-6.5.invokevirtual.runtime-110-C]
...
Discussion and motivation:
It is possible that theMethodrefof aninvokevirtualinstruction resolves to an interface method. In this case, it is possible that there is no overriding method in the class hierarchy, but that a non-abstractinterface method matches the resolved method's signature. The selection logic has been modified to match such a method, using the same rules as those forinvokeinterface.Again, this change is designed to be retroactive: an
invokevirtualoccurring in an old class file may have the effect of invoking a non-abstractinterface method declared in a new class file. Given the restructured selection logic, it is no longer necessary to separately mandate anAbstractMethodErrorif nothing is found. So that clause has been removed (but the behavior in that case is unchanged).