preface

Because Java8 introduced functional interfaces, methods of Java classes can be treated as functions, such as: Comparator

comparatorFunction = Integer::compareTo. A method reference is just a syntactic sugar, and what you get from a method reference is essentially a function object. So the question is how does the Java compiler know that the interface of the Integer::compareTo function is a Comparator and not something else? Answering this question requires understanding the use of method references and the mechanism for matching function types.

Method reference category

There are four types of method references described in the Javase documentation:

  • Static methods refer to the name of the class: : static method (ContainingClass: : staticMethodName)
  • Specific object instance method reference: : instance methods (containingObject: : instanceMethodName)
  • Reference to an instance method of an arbitrary object of a particular type The name of the class: : instance methods (ContainingType: : methodName)
  • The constructor references ClassName::new the ClassName::new

Taking the Integer class as an example, the four method references are as follows:

        Integer instance = Integer.valueOf(10);
        BiFunction<String, Integer, Integer> parseIntFunction = Integer::parseInt; Static method references
        Function<Integer, Integer> compareToInstanceFunction = instance::compareTo;// An instance method reference for a specific object
        Comparator<Integer> comparatorFunction = Integer::compareTo; // An instance method reference for any object
        Comparator<String> compareToIgnoreCase = String::compareToIgnoreCase; // An instance method reference for any object
        Function<String, Integer> constructorFunction = Integer::new;// constructor method reference
        IntFunction<Integer> intConstructorFunction = Integer::new;// constructor method reference
Copy the code

Mechanism for matching function types

Matching of function types:

  • The method name is not important, according to the method parameter to determine whether conform to, such as: Integer: : compareTo and String: : compareToIgnoreCase
  • Either method reference may match multiple function interfaces, such as Integer::new in the previous example
  • Static method references/constructor method references do not involve instances, so match function types directly based on the number and type of arguments
  • The instance method reference of a particular object, because it is a method reference on an instance, matches the function type, also directly based on the number and type of arguments
  • An instance method reference of any object is a special one. It is obtained by the class name, but it needs to know on which instance it will be executed. Therefore, when it matches the function type, it will add an argument of its own type as the first argument, such as Integer::compareTo, There is only one argument (Integer I), but when the function is matched, it takes (Integer I, Integer j) to match. In this example, both the parameter type and its type are Integer, so it’s not easy to tell. Here’s an easy to understand example:BiFunction<String, Integer, String> stringBiFunction = String::substring;, subString has only one int argument, but it will match BiFunction and the first argument is String.