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

  • If method lookup failed, interface method resolution throws a NoSuchMethodError.

  • Otherwise, method lookup succeeded. Access control is applied for the access from D to the method which is the result of method lookup (§5.4.4). Then:

    • If access control failed, interface method resolution fails for the same reason.

    • Otherwise, access control succeeded. Loading constraints are imposed, as follows.

      Let <E, L1> be the class or interface in which the referenced interface method m is actually declared. Let L2 be the defining loader of D. Given that the return type of m is Tr, and that the formal parameter types of m are Tf1, …​, Tfn:

      If Tr is not an array type, let T0 be Tr; otherwise, let T0 be the element type 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 of Tfi.

      The Java Virtual Machine imposes the loading constraints TiL1 = TiL2 for i = 0 to n.

      If imposing these constraints results in any loading constraints being violated (§5.3.4), then interface method resolution fails. Otherwise, interface method resolution succeeds. Access control is necessary because interface method resolution may pick a private method of interface C. (Prior to Java SE 8, the result of interface method resolution could be a non-public method of class Object or a static method of class Object; such results were not consistent with the inheritance model of the Java programming language, and are disallowed in Java SE 8 and above.)

贡献翻译,请加 QQ: 840750575    点击这里给我发消息
数码
沪ICP备19006215号-4