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 its nestmates (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 its nestmates (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 Seven 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 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 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

4.7.28 The NestHost Attribute

The 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).

4.7.29 The NestMembers Attribute

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

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

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 (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:

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:

...

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:

...

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

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:

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 (that is, whether C and D are nestmates), the following steps are performed:

  1. If C and D are the same class or interface, they belong to the same nest.

  2. Otherwise, the nest host of D, H, is determined. If an exception is thrown, the nest membership test fails for the same reason.

  3. Otherwise, the nest host of C, H', is determined. If an exception is thrown, the nest membership test fails for the same reason.

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

  1. If M lacks a NestHost attribute (4.7.28), M is its own nest host.

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

  3. If resolution of H succeeds, but H is not declared in the same run-time package as M, an IncompatibleClassChangeError is thrown.

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

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

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.

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:

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:

  1. If C contains a declaration for an instance method m that can override the resolved method, then m is the selected method.

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

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

6.5 invokeinterface

...

Description

...

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.

  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.

This change allows invokeinterface to 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 the selected method is a method that is not public 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 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.

...

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: The selected method (5.4.5) for class C of an invocation of the referenced method is the actual 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:

...