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:

  1. 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.

  2. Modifying the behavior of invokeinterface to support invocation of private methods.

2.11.8 Method Invocation and Return Instructions

The following five instructions 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.

3.7 Invoking 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 private methods. For instance, given classes Near 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.

...

4.5 Fields

...

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.

...

4.6 Methods

...

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_SYNCHORNIZED 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 by platform-specific code.
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.

...

4.7 Attributes

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:

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:

  1. Five Six attributes are critical to correct interpretation of the class file by the Java Virtual Machine:

    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.

  2. Eight Nine 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"):

    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.

  3. 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"):

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, 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

4.7.28 The NestHost Attribute

The NestHost attribute is a fixed-length attribute in the attributes table of a ClassFile structure (4.1). The NestHost attribute records the nest host of the nest to which the current class or interface claims to belong (5.4.4).

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 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, 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). 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 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 which is a member of the nest hosted by the current class or interface.

The classes array is consulted during access control (5.4.4). It should consist of references to other classes and interfaces that are in the same run-time package and have NestHost attributes which reference the current class or interface. Array items that do not meet these criteria are ignored by access control.

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 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 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. The Java Virtual Machine imposes the following constraints loading constraints as follows:

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 and new 5.4.6 to more precisely define when loader constraints are introduced. It addresses JDK-8078636, which notes that "inherited" is undefined.

5.4.3.1 Class and Interface Resolution

To resolve an unresolved symbolic reference from D to a class or interface C denoted by N, the following steps are performed:

  1. 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.

  2. 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.

  3. Finally, access permissions to C are checked control is applied for the access from D to C (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.

5.4.3.2 Field Resolution

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:

  1. 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.

  2. Otherwise, field lookup is applied recursively to the direct superinterfaces of the specified class or interface C.

  3. Otherwise, if C has a superclass S, field lookup is applied recursively to S.

  4. Otherwise, field lookup fails.

Then, the result of field resolution is determined:

5.4.3.3 Method Resolution

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:

  1. If C is an interface, method resolution throws an IncompatibleClassChangeError.

  2. Otherwise, method resolution attempts to locate the referenced method in C and its superclasses: ...

  3. 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 as follows:

...

5.4.3.4 Interface Method Resolution

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:

  1. If C is not an interface, interface method resolution throws an IncompatibleClassChangeError.

  2. Otherwise, if C declares a method with the name and descriptor specified by the interface method reference, method lookup succeeds.

  3. 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.

  4. 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.

  5. 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.

  6. Otherwise, method lookup fails.

The result of interface method resolution is determined by whether method lookup succeeds or fails as follows:

...

5.4.3.5 Method Type and Method Handle Resolution

...

To resolve MH, all symbolic references to classes, interfaces, fields, and methods in MH's bytecode behavior are resolved, using the following four steps:

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, and static members can be created in exactly those classes for which the corresponding normal accesses are legal.

...

5.4.4 Access Control

Access control is applied during resolution (5.4.3) to ensure that a reference to a class, interface, field, or method is permitted. Access control succeeds if a specificed class, interface, field, or method is accessible to the referring class or interface.

This section has been modified slightly to describe a set of errors that may occur during "access control", rather than merely defining a simple boolean "is accessible" predicate. This is because class resolution now occurs during access control, 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:

If C is not accessible to D, access control throws an IllegalAccessError. Otherwise, access control succeeds.

A field or method R is accessible to a class or interface D if and only if any of the following is true:

If R is not accessible to D, then:

Otherwise, access control succeeds.

A nest is a set of classes and interfaces that allow mutual access to their private members. One of the classes or interfaces is the nest host. It enumerates the classes and interfaces which belong to the nest, using the NestMembers attribute (4.7.29). Each of them in turn designates it as the nest host, using the NestHost attribute (4.7.28). A class or interface which lacks a NestHost attribute belongs to the nest hosted by itself; if it also lacks a NestMembers attribute, this nest is a singleton consisting only of the class or interface itself.

To determine whether a class or interface C belongs to the same nest a class or interface D, the nestmate test is applied. C and D belong to the same nest if and only if the nestmate test succeeds. The nestmate test is as follows:

The nest host of a class or interface M is determined as follows:

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 control, and class access control depends on nest host resolution.

5.4.5 Overriding

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:

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.

Part (b) of the final case allows for "transitive overriding" of methods with default access. For example, given the following class declarations in a package P:

public class A { void m() {} }
public class B extends A { public void m() {} }
public class C extends B { void m() {} }

and then the following class declaration in a different package:

public class D extends P.C { void m() {} }

Then:

5.4.6 Method Selection

During execution of an invokeinterface or invokevirtual instruction, a method is selected with respect to (i) the run-time type of the object on the stack, and (ii) a method that was previously resolved by the instruction. The rules to select a method with respect to a class or interface C and a method mR are as follows:

  1. If mR is marked ACC_PRIVATE, then it is the selected method.

  2. Otherwise, the selected method is determined by the following lookup procedure:

    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:

6.5 invokeinterface

...

Description

...

Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: A method is selected with respect to C and the resolved method (5.4.6). This is the method to be invoked.

  1. 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.

  2. 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.

  3. 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.

...

Linking Exceptions

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 private, the invokeinterface instruction throws an IncompatibleClassChangeError.

Note that invokeinterface may refer to private methods declared in interfaces, including nestmate interfaces.

Run-time Exceptions

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 the selected method is neither public nor private, invokeinterface throws an IllegalAccessError.

This change allows private methods to be selected.

Selection of package and protected methods is still restricted, to prevent subclasses from gaining unauthorized access to members of their superclasses. See JDK-8024806.

Otherwise, if step 1 or step 2 of the lookup procedure selects an abstract method the selected method is abstract, invokeinterface throws an AbstractMethodError.

Otherwise, if step 1 or step 2 of the lookup procedure selects a native method the selected method is native and the code that implements the method cannot be bound, invokeinterface throws an UnsatisfiedLinkError.

Otherwise, if step 3 of the lookup procedure determines no method is selected, and there are multiple maximally-specific superinterface 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 step 3 of the lookup procedure determines no method is selected, and there are zero no maximally-specific superinterface methods in the superinterfaces of C that match the resolved method's name and descriptor and are not abstract, invokeinterface throws an AbstractMethodError.

...

6.5 invokespecial

Operation

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

...

Notes

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 private methods and methods of a superclass of the current class methods of the current class and its supertypes.

The invokespecial instruction was named invokenonvirtual 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 private interface method, a non-abstract interface method, referenced either via a direct superinterface, and a non-abstract interface method referenced via or 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).

6.5 invokevirtual

...

Description

...

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: A method is selected with respect to C and the resolved method (5.4.6). This is the method to be invoked.

  1. 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.

  2. 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.

  3. 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.

...

Linking Exceptions

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.

Run-time Exceptions

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:

Otherwise, if the resolved method is signature polymorphic, then:

...