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.
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.
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]
Object
. [jsr335-15.28-22-A]
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:
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 asuper
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. 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.
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. 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.
Compare JLS 3.11
Nine Ten tokens, formed from ASCII characters, are the separators (punctuators). [jls-3.11-100]
Separator: one of ... ',' '.' '::'