Lambda Specification, Part C: Method References

Navigation: Overview - Part A - Part B - Part C - Part D - Part E - Part F - Part G - Part H - Part J
Sections: 15.28 - 3.11
Version 0.6.2. Copyright © 2012 Oracle America, Inc. Legal Notice.

Summary

A method reference is used to refer to the invocation of a method without actually performing the invocation. Certain forms of method references also allow class instance creation or array creation to be treated as if it were a method invocation.

Examples of method references:

System::getProperty
"abc"::length
String::length
super::toString
ArrayList::new
int[]::new

The target reference (i.e., the "receiver") of an instance method may be provided by the method reference expression or it may be provided later when the method is invoked. The immediately enclosing instance of an inner class instance must be provided by a lexically enclosing instance of this.

When more than one member method of a type has the same name, or when a class has more than one constructor, the appropriate method or constructor is selected based on the function type targeted by the expression.

15.28 Method Reference Expressions [New]

A method reference is used to refer to the invocation of a method without actually performing the invocation. Certain forms of method references also allow class instance creation (15.9) or array creation (15.10) to be treated as if it were a method invocation.

MethodReference:
 ExpressionName '::' NonWildTypeArgumentsopt Identifier
 Primary '::' NonWildTypeArgumentsopt Identifier
 'super' '::' NonWildTypeArgumentsopt Identifier
 TypeName '.' 'super' '::' NonWildTypeArgumentsopt Identifier
 ReferenceType '::' NonWildTypeArgumentsopt Identifier
 ClassType '::' NonWildTypeArgumentsopt 'new'
 ArrayType '::' 'new'

The following productions from 8.8.7.1 are repeated here for convenience:

NonWildTypeArguments:
 '<' ReferenceTypeList '>'

ReferenceTypeList:
 ReferenceType
 ReferenceTypeList ',' ReferenceType

It is a compile-time error if a method reference has the form ExpressionName :: NonWildTypeArgumentsopt Identifier or Primary :: NonWildTypeArgumentsopt Identifier, and the type of the ExpressionName or Primary is not a reference type. [jsr335-15.28-5]

If a method reference has the form super :: NonWildTypeArgumentsopt Identifier, let T be the type declaration immediately enclosing the method reference. It is a compile-time error if T is the class Object or T is an interface. [jsr335-15.28-21]

If a method reference has the form TypeName . super :: NonWildTypeArgumentsopt Identifier, then: [jsr335-15.28-22]

The above restrictions mimic 15.12.1 (as modified by this specification). (We could avoid stating them here, because 15.28.1 is defined in terms of 15.12.1, but it's more straightforward to be explicit about it.)

It is a compile-time error if a method reference of the form super :: NonWildTypeArgumentsopt Identifier or of the form TypeName . super :: NonWildTypeArgumentsopt Identifier occurs in a static context. [jsr335-15.28-20]

The above restriction mimics 15.12.3.

If a method reference has the form ClassType :: NonWildTypeArgumentsopt new, the ClassType must denote a class that is accessible (6.6) and is not an enum type and not abstract, or a compile-time error occurs. [jsr335-15.28-10]

The above restriction mimics 15.9.1.

In addition, if a method reference has the form ClassType :: NonWildTypeArgumentsopt new, it is a compile-time error if any of the type arguments used in the ClassType are wildcard type arguments (4.5.1). [jsr335-15.28-11]

The above restriction mimics 15.9.

If a method reference has the form ArrayType :: new, the ArrayType must denote a type that is reifiable (4.7), or a compile-time error occurs. [jsr335-15.28.15]

The above restriction mimics 15.10.

The target reference of an instance method (15.12.4.1) may be provided by the method reference expression—using an ExpressionName, a Primary, or super—or it may be provided later when the method is invoked. The immediately enclosing instance of an inner class instance (15.9.2) must be provided by a lexically enclosing instance of this (8.1.3).

When more than one member method of a type has the same name, or when a class has more than one constructor, the appropriate method or constructor is selected based on the function type targeted by the expression.

If a method or constructor is generic, the appropriate type arguments may either be inferred or provided explicitly. Similarly, the type arguments of a generic type mentioned by the method reference may be provided explicitly or inferred.

Examples of method reference expressions:
System::getProperty
String::length
List<String>::size   // explicit class type args
List::size           // inferred class type args
int[]::clone
T::tvarMember

"abc"::length
foo[x]::bar
(test ? list.map(String::length) : Collections.emptyList())::iterator
super::toString

String::valueOf      // overload resolution needed     
Arrays::sort         // type args inferred from context
Arrays::<String>sort // explicit type args

ArrayList<String>::new    // constructor for parameterized type
ArrayList::new            // inferred class type args
Foo::<Integer>new         // explicit generic constructor type arguments
Bar<String>::<Integer>new // generic class, generic constructor
Outer.Inner::new          // inner class constructor
int[]::new                // array creation
Discussion and motivation:
  1. The term "method reference" is imprecise, but captures the typical usage of the feature. In full generality, method references are shorthand to describe certain expressions that should not be evaluated until a future point. Hence, the same method can be referenced via a standard invocation or a super invocation—properties of the implicit invocation expression, not the method itself. Similarly, class instance creation and array creation can be referenced, even though there is no actual corresponding method that returns a class instance or an array.
  2. There is no support for specifying a particular signature to be matched:
    Arrays::sort(int[])

    Instead, the functional interface provides argument types that are used as input to the overload resolution algorithm (15.12.2). This should satisfy the vast majority of use cases; when the rare need arises for more precise control, a lambda expression can be used.

  3. The method reference delimiter is infix; this seems useful because it clearly separates the "evaluated now" portion of the expression from the "evaluated on invocation" part. It also conveys the useful model that a method reference is sort of like a new kind of member of an object or class.

    Other languages simply use a method name as a method reference—the delimiter would be '.'. But this introduces ambiguities with field names, so it is useful to have a unique delimiter to differentiate.

  4. The use of type argument syntax in the class name before a delimiter (List<String>::size) raises the parsing problem of distinguishing between '<' as a type argument bracket and '<' as a less-than operator; this problem does not arise in a static method invocation. In theory, this is no worse than allowing type arguments in cast expressions; however, the difference is that the cast case only comes up when a '(' token is encountered; with the addition of method references, the start of every expression is potentially a parameterized type.
  5. Section 15.28 is currently the last section in chapter 15 and defines constant expressions. To reasonably accommodate the chapter structure without drastically changing section numbers, this has been bumped forward to 15.29 and 15.28 has been repurposed to address method and constructor references.

3.11 Separators [Modified]

Compare JLS 3.11

Nine Ten tokens, formed from ASCII characters, are the separators (punctuators). [jls-3.11-100]

Separator: one of
  ...
  ','
  '.'
  '::'