Method Invocation Expressions

时间:2023-12-06 11:32:50
15.12.1. Compile-Time Step 1: Determine Class or Interface to Search
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to check for definitions of methods of that name. There are several cases to consider, depending on the form that precedes the left parenthesis, as follows.
有几种情况需要考虑,取决于左括号前面的形式,如下:
1、If the form is MethodName, then there are three subcases:
1-A、If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier.
If the Identifier appears within the scope of a visible method declaration with that name (§6.3§6.4.1), then:
1-A-(1)、If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration(
让T是最内层的类型声明). The class or interface to search is T.
This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See §6.5.7.1 for an example.
1-A-(2)、 Otherwise, the visible method declaration may be in scope due to one or more single-static-import or static-import-on-demand declarations (§7.5.3§7.5.4). There is no class or interface to search, as the method to be invoked is determined later (§15.12.2).
1-B、If it is a qualified name of the form TypeName.Identifier, then the name of the method is the Identifier and the class to search is the one named by the TypeName.
If TypeName is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only static methods and interfaces have no static methods.
1-C、In all other cases, the qualified name has the form FieldName . Identifier.
The name of the method is the Identifier and the class or interface to search is the declared type T of the field named by the FieldName, if T is a class or interface type, or the upper bound of T if T is a type variable.
2、If the form is Primary . NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier.
Let T be the type of the Primary expression. The class or interface to be searched is T if T is a class or interface type, or the upper bound of T if T is a type variable.
It is a compile-time error if T is not a reference type.

2-A、If the form is super . NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier and the class to be searched is the superclass of the class whose declaration contains the method invocation.

Let T be the type declaration immediately enclosing the method invocation. It is a compile-time error if T is the class Object or T is an interface.

2-B、If the form is ClassName . super . NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier and the class to be searched is the superclass of the class C denoted by ClassName.

It is a compile-time error if C is not a lexically enclosing class of the current class.
It is a compile-time error if C is the class Object.
Let T be the type declaration immediately enclosing the method invocation(令T是直接包含方法调用的类型声明). It is a compile-time error if T is the class Object or T is an interface.

2-C、If the form is TypeName . NonWildTypeArguments Identifier, then the name of the method is the Identifier and the class to be searched is the class C denoted by TypeName.

If TypeName is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only static methods and interfaces have no static methods.
15.12.2. Compile-Time Step 2: Determine Method Signature 决定方法签名
The second step searches the type determined in the previous step for member methods. This step uses the name of the method and the types of the argument expressions to locate methods that are both accessible and applicable(合适的), that is, declarations that can be correctly invoked on the given arguments.
There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is one used at run time to perform the method dispatch.
A method is applicable if it is either applicable by subtyping (§15.12.2.2), applicable by method invocation conversion (§15.12.2.3), or it is an applicable variable arity method (§15.12.2.4).
The process of determining applicability begins by determining the potentially applicable methods (§15.12.2.1).
The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:
  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.
  1. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.
  1. The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
Deciding whether a method is applicable will, in the case of generic methods (§8.4.4), require that type arguments be determined. Type arguments may be passed explicitly or implicitly. If they are passed implicitly, they must be inferred (§15.12.2.7) from the types of the argument expressions.
If several applicable methods have been identified during one of the three phases of applicability testing, then the most specific one is chosen, as specified in section §15.12.2.5.