Copyright © 2017 Oracle America, Inc. Legal Notice.
This document proposes changes to the Java Language Specification to improve the usability of the lambda expression language feature. See JEP 302 for an overview.
A declaration introduces an entity into a program and usually includes an identifier (3.8) that can be used in a name to refer to this entity.
This unqualified statement was already incorrect (anonymous classes, for example, are declared but have no name), and will be even more dubious with the introduction of unnamed parameters.
...
...
The scope of a named formal parameter of a method (8.4.1), constructor (8.8.1), or lambda expression (15.27) is the entire body of the method, constructor, or lambda expression.
...
The scope of a named parameter of an exception handler that is declared in a catch
clause of a try
statement (14.20) is the entire block associated with the catch
.
...
A local variable (14.4), formal parameter (8.4.1, 15.27.1), exception parameter (14.20), and local class (14.3) can only be referred to using a simple name, not a qualified name (6.2).
Some declarations are not permitted within the scope of a local variable, formal parameter, exception parameter, or local class declaration because it would be impossible to distinguish between the declared entities using only simple names.
For example, if the name of a formal parameter of a method could be redeclared as the name of a local variable in the method body, then the local variable would shadow the formal parameter and the formal parameter would no longer be visible—an undesirable outcome.
It is a compile-time error if the name of a formal parameter is used to declare a new variable within the body of the method, constructor, or lambda expression, unless the new variable is declared within a class declaration or lambda expression contained by the method, constructor, or lambda expression.
It is a compile-time error if the name of a local variable v is used to declare a new variable within the scope of v, unless the new variable is declared within a class whose declaration is within a class declaration or lambda expression contained by the scope of v.
It is a compile-time error if the name of an exception parameter is used to declare a new variable within the Block of the catch
clause, unless the new variable is declared within a class declaration or lambda expression contained by the Block of the catch
clause.
It is a compile-time error if the name of a local class C is used to declare a new local class within the scope of C, unless the new local class is declared within another class whose declaration is within another class declaration or a lambda expression contained by the scope of C.
These rules allow redeclaration of a variable or local class in nested class declarations (local classes (14.3) and anonymous classes (15.9)) and lambda expressions that occur in the scope of the variable or local class. Thus, the declaration of a formal parameter, local variable, or local class may be shadowed in a class declaration or lambda expression nested within a method, constructor, or lambda expression; and the declaration of an exception parameter may be shadowed inside a class declaration or lambda expression nested within the Block of the
catch
clause.
There are two design alternatives for handling name clashes created by lambda parameters and other variables declared in lambda expressions. One is to mimic class declarations: like local classes, lambda expressions introduce a new "level" for names, and all variable names outside the expression can be redeclared. Another is a "local" strategy: like catch clauses, for loops, and blocks, lambda expressions operate at the same "level" as the enclosing context, and local variables outside the expression cannot be shadowed. The above rules use the local strategy; there is no special dispensation that allows a variable declared in a lambda expression to shadow a variable declared in an enclosing method.
Note that the rule for local classes does not
make an exception forrestrict the declaration of a member class of the same name declared within the local classitself. However, this case is prohibited by a separate rule: a class cannot have the same name as a class that encloses it (8.1).
...
The formal parameters of a method or constructor, if any, are specified by a list of comma-separated parameter specifiers. Each parameter specifier consists of a type (optionally preceded by the declares a type for the variable and, optionally, a name.final
modifier and/or one or more annotations) and an identifier (optionally followed by brackets) that specifies the name of the parameter
If a method or constructor has no formal parameters, only an empty pair of parentheses appears in the declaration of the method or constructor.
FormalParameterList:
FormalParameters [
,
VariableArityParameter ]
VariableArityParameter
ReceiverParameter [,
FormalParameters ] [,
VariableArityParameter ]
FormalParameters:
FormalParameter {
,
FormalParameter }
ReceiverParameter {,
FormalParameter }
FormalParameter:
{ VariableModifier } UnannType
VariableDeclaratorIdParameterName [ Dims ]
VariableModifier:
(one of)
Annotationfinal
ParameterName:
Identifier
_
ReceiverParameter:
{ Annotation } UnannType [ Identifier
.
] this
LastFormalParameter:VariableArityParameter:{ VariableModifier } UnannType { Annotation }
...
ParameterName
FormalParameter
This attempts to clean up the somewhat convoluted treatment of receiver parameters and variable-arity parameters in the old grammar. In this presentation, a parameter is always exactly one of a (standard) FormalParameter, a ReceiverParameter, or a VariableArityParameter. The rules for how they are arranged are managed solely by FormalParameterList.
The following production from 4.3
and 8.3is shown here for convenience:
VariableDeclaratorId:
Identifier [ Dims ]Dims:
{ Annotation }
[
]
{ { Annotation }[
]
}
A formal parameter's ParameterName may be an Identifier that names the parameter. If the ParameterName is instead the keyword _
, the parameter is an unnamed parameter.
It is a compile-time error if the ParameterName _
is followed by Dims.
The scope and shadowing of a named formal parameter is specified in 6.3 and 6.4. The Identifier that appears as the ParameterName may be used as a simple name in the body of the method or constructor to refer to the formal parameter.
An unnamed parameter has no name or scope (6.3).
This means that the variable cannot be referenced (6.5.6.1). It also means that multiple unnamed parameters can be declared in the same formal parameter list.
Note that an unnamed parameter is still a variable. So, for example, any necessary conversions required by method invocation in order to initialize the variable (5.3) must occur.
For compilation, note that the MethodParameters
attribute of the class file already supports unnamed parameters via a zero constant pool pointer (JVMS 4.7.24).
The last formal parameter of a method or constructor is special: it may be a variable arity parameter, indicated by an ellipsis following the type.
Note that the ellipsis (
...
) is a token unto itself (3.11). It is possible to put whitespace between it and the type, but this is discouraged as a matter of style.
If the last formal parameter is a variable arity parameter, the method is a variable arity method. Otherwise, it is a fixed arity method.
The receiver parameter is an optional syntactic device for an instance method or an inner class's constructor. For an instance method, the receiver parameter represents the object for which the method is invoked. For an inner class's constructor, the receiver parameter represents the immediately enclosing instance of the newly constructed object. Either way, the receiver parameter exists solely to allow the type of the represented object to be denoted in source code, so that the type may be annotated. The receiver parameter is not a formal parameter; more precisely, it is not a declaration of any kind of variable (4.12.3), it is never bound to any value passed as an argument in a method invocation expression or qualified class instance creation expression, and it has no effect whatsoever at run time.
The rules for annotation modifiers on a formal parameter declaration and on a receiver parameter are specified in 9.7.4 and 9.7.5.
It is a compile-time error if final
appears more than once as a modifier for a formal parameter declaration.
It is a compile-time error to use mixed array notation (10.2) for a variable arity parameter.
The revised grammar makes this impossible.
The scope and shadowing of a formal parameter is specified in 6.3 and 6.4.
This assertion was moved to an earlier point in this section.
It is a compile-time error for a method or constructor to declare two formal parameters with the same name. (That is, their declarations mention the same Identifier.)
It is a compile-time error if a formal parameter that is declared final
is assigned to within the body of the method or constructor.
The declaration final int _
is legal per the FormalParameter grammar rule, even though it's impossible to assign to an unnamed parameter, final
or not. We could flag this as an error, but the modifier is harmless and might be relevant in certain use cases involving reflection or debugging.
A receiver parameter may appear only in the FormalParameterList of an instance method or an inner class's constructor; otherwise, a compile-time error occurs.
Where a receiver parameter is allowed, its type and name are specified as follows:
In an instance method, the type of the receiver parameter must be the class or interface in which the method is declared, and the name of the receiver parameter must be this
; otherwise, a compile-time error occurs.
In an inner class's constructor, the type of the receiver parameter must be the class or interface which is the immediately enclosing type declaration of the inner class, and the name of the receiver parameter must be Identifier .
this
where Identifier is the simple name of the class or interface which is the immediately enclosing type declaration of the inner class; otherwise, a compile-time error occurs.
The declared type of a formal parameter depends on whether it is a variable arity parameter:
If the formal parameter is not a variable arity parameter, then the declared type is denoted by UnannType if no bracket pairs appear in UnannType and VariableDeclaratorId or immediately after the ParameterName, and specified by 10.2 otherwise.
If the formal parameter is a variable arity parameter, then the declared type is specified by 10.2. (Note that "mixed notation" is not permitted for variable arity parameters.)
If the declared type of a variable arity parameter has a non-reifiable element type (4.7), then a compile-time unchecked warning occurs for the declaration of the variable arity method, unless the method is annotated with @SafeVarargs
(9.6.4.7) or the unchecked warning is suppressed by @SuppressWarnings
(9.6.4.5).
When the method or constructor is invoked (15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.
This assertion was moved to an earlier point in this section.
Invocations of a variable arity method may contain more actual argument expressions than formal parameters. All the actual argument expressions that do not correspond to the formal parameters preceding the variable arity parameter will be evaluated and the results stored into an array that will be passed to the method invocation (15.12.4.2).
A method or constructor parameter of type float
always contains an element of the float value set (4.2.3); similarly, a method or constructor parameter of type double
always contains an element of the double value set. It is not permitted for a method or constructor parameter of type float
to contain an element of the float-extended-exponent value set that is not also an element of the float value set, nor for a method parameter of type double
to contain an element of the double-extended-exponent value set that is not also an element of the double value set.
Where an actual argument expression corresponding to a parameter variable is not FP-strict (15.4), evaluation of that actual argument expression is permitted to use intermediate values drawn from the appropriate extended-exponent value sets. Prior to being stored in the parameter variable, the result of such an expression is mapped to the nearest value in the corresponding standard value set by being subjected to invocation conversion (5.3).
...
...
The array type of a variable depends on the bracket pairs that may appear as part of the type at the beginning of a variable declaration, or as part of the declarator for the variable following the Identifier naming the variable, or both. Specifically, in the declaration of a field, formal parameter, or local variable (8.3, 8.4.1, 9.3, 9.4, 14.4.1, 14.14.2, 15.27.1), the array type of the variable is denoted by:
...
try
StatementA try
statement executes a block. If a value is thrown and the try
statement has one or more catch
clauses that can catch it, then control will be transferred to the first such catch
clause. If the try
statement has a finally
clause, then another block of code is executed, no matter whether the try
block completes normally or abruptly, and no matter whether a catch
clause is first given control.
TryStatement:
try
Block Catchestry
Block [ Catches ] Finally
TryWithResourcesStatement
Catches:
CatchClause { CatchClause }
CatchClause:
catch
(
CatchFormalParameter)
Block
CatchFormalParameter:
{ VariableModifier } CatchType ParameterName
CatchType:
UnannClassType {
|
ClassType }
Finally:
finally
Block
See 8.3 for UnannClassType. The following productions from
4.3, 8.3, and8.4.1 are shown here for convenience:VariableModifier:
(one of) Annotation
final
VariableDeclaratorId:
Identifier [ Dims ]
Dims:
{ Annotation }[
]
{ { Annotation }[
]
}ParameterName:
Identifier
_
The Block immediately after the keyword try
is called the try
block of the try
statement.
The Block immediately after the keyword finally
is called the finally
block of the try
statement.
A try
statement may have catch
clauses, also called exception handlers.
A catch
clause declares exactly one parameter, which is called an exception parameter.
An exception parameter's ParameterName may be an Identifier that names the parameter. If the ParameterName is instead the keyword _
, the parameter is an unnamed parameter.
The scope and shadowing of a named exception parameter is specified in 6.3 and 6.4. The Identifier that appears as the ParameterName may be used as a simple name in the body of the catch
clause to refer to the exception parameter.
An unnamed parameter has no name or scope (6.3).
It is a compile-time error if final
appears more than once as a modifier for an exception parameter declaration.
The scope and shadowing of an exception parameter is specified in 6.3 and 6.4.
...
The formal parameters of a lambda expression may have either declared types or inferred types. These styles cannot be mixed: it is not possible for a lambda expression to declare the types of some of its parameters but leave others to be inferred. Only parameters with declared types can have modifiers.
LambdaParameters:
IdentifierParameterName
(
[ FormalParameterList ])
(
InferredFormalParameterList)
InferredFormalParameterList:
ParameterName {
,
ParameterName }
The following productions from 4.3
8.3,and 8.4.1 are shown here for convenience:FormalParameterList:
FormalParameters [
,
VariableArityParameter ]
VariableArityParameter
ReceiverParameter [,
FormalParameters ] [,
VariableArityParameter ]FormalParameters:
FormalParameter {
,
FormalParameter }
ReceiverParameter {,
FormalParameter }FormalParameter:
{ VariableModifier } UnannType
VariableDeclaratorIdParameterName [ Dims ]
LastFormalParameter:VariableArityParameter:{ VariableModifier } UnannType { Annotation }
...
ParameterName
FormalParameterVariableModifier:
(one of)
Annotationfinal
ParameterName:
Identifier
_
Dims:
{ Annotation }
[
]
{ { Annotation }[
]
}Receiver parameters are not permitted in the FormalParameters of a lambda expression, as specified in 8.4.1.
A lambda expression whose formal parameters have declared types is said to be explicitly typed, while a lambda expression whose formal parameters have inferred types is said to be implicitly typed. A lambda expression with zero parameters is explicitly typed.
If the formal parameters have inferred types, then these types are derived (15.27.3) from the functional interface type targeted by the lambda expression.
The syntax for formal parameters with declared types is the same as the syntax for the parameters of a method declaration (8.4.1).
The declared type of a formal parameter depends on whether it is a variable arity parameter:
If the formal parameter is not a variable arity parameter, then the declared type is denoted by UnannType if no bracket pairs appear in UnannType and VariableDeclaratorId or immediately after the ParameterName, and specified by 10.2 otherwise.
If the formal parameter is a variable arity parameter, then the declared type is specified by 10.2. (Note that "mixed notation" is not permitted for variable arity parameters.)
No distinction is made between the following lambda parameter lists:
(int... x) -> .. (int[] x) -> ..
Consistent with the rules for overriding, either can be used, whether the functional interface's abstract method is fixed arity or variable arity. Since lambda expressions are never directly invoked, introducing
int...
where the functional interface usesint[]
can have no impact on the surrounding program. In a lambda body, a variable arity parameter is treated just like an array-typed parameter.
The rules for annotation modifiers on a formal parameter declaration are specified in 9.7.4 and 9.7.5.
It is a compile-time error if final
appears more than once as a modifier for a formal parameter declaration.
It is a compile-time error to use mixed array notation (10.2) for a variable arity parameter.
A lambda parameter's ParameterName may be an Identifier that names the parameter. If the ParameterName is instead the keyword _
, the parameter is an unnamed parameter.
The scope and shadowing of a formal parameter declaration named lambda parameter is specified in 6.3 and 6.4. The Identifier that appears as the ParameterName may be used as a simple name in the lambda body to refer to the lambda parameter.
An unnamed parameter has no name or scope (6.3).
It is a compile-time error for a lambda expression to declare two formal parameters with the same name. (That is, their declarations mention the same Identifier.)
It is a compile-time error if a receiver parameter (8.4.1) appears in the FormalParameters of a lambda expression.
This is redundant: it was already covered in the note following the grammar rules.
It is a compile-time error if a formal parameter that is declared final
is assigned to within the body of the lambda expression.
When the lambda expression is invoked (via a method invocation expression (15.12)), the values of the actual argument expressions initialize newly created parameter variables, each of the declared or inferred type, before execution of the lambda body. The Identifier that appears in the VariableDeclaratorId or the InferredFormalParameterList may be used as a simple name in the lambda body to refer to the formal parameter.
...
Copyright © 2017 Oracle America, Inc. 4150 Network Circle, Santa Clara, California 95054, U.S.A. All rights reserved.
The Specification is protected by copyright and the information described therein may be protected by one or more U.S. patents, foreign patents, or pending applications. Except as provided under the following license, no part of the Specification may be reproduced in any form by any means without the prior written authorization of Oracle America, Inc. ("Oracle") and its licensors, if any. Any use of the Specification and the information described therein will be governed by the terms and conditions of this Agreement.
Subject to the terms and conditions of this license, including your compliance with Paragraphs 1 and 2 below, Oracle hereby grants you a fully-paid, non-exclusive, non-transferable, limited license (without the right to sublicense) under Oracle's intellectual property rights to:
Review the Specification for the purposes of evaluation. This includes: (i) developing implementations of the Specification for your internal, non-commercial use; (ii) discussing the Specification with any third party; and (iii) excerpting brief portions of the Specification in oral or written communications which discuss the Specification provided that such excerpts do not in the aggregate constitute a significant portion of the Technology.
Distribute implementations of the Specification to third parties for their testing and evaluation use, provided that any such implementation:
does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other than those required/authorized by the Specification or Specifications being implemented;
is clearly and prominently marked with the word "UNTESTED" or "EARLY ACCESS" or "INCOMPATIBLE" or "UNSTABLE" or "BETA" in any list of available builds and in proximity to every link initiating its download, where the list or link is under Licensee's control; and
includes the following notice: "This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and is made available for testing and evaluation purposes only. The code is not compatible with any specification of the JCP."
The grant set forth above concerning your distribution of implementations of the specification is contingent upon your agreement to terminate development and distribution of your "early draft" implementation as soon as feasible following final completion of the specification. If you fail to do so, the foregoing grant shall be considered null and void.
No provision of this Agreement shall be understood to restrict your ability to make and distribute to third parties applications written to the Specification.
Other than this limited license, you acquire no right, title or interest in or to the Specification or any other Oracle intellectual property, and the Specification may only be used in accordance with the license terms set forth herein. This license will expire on the earlier of: (a) two (2) years from the date of Release listed above; (b) the date on which the final version of the Specification is publicly released; or (c) the date on which the Java Specification Request (JSR) to which the Specification corresponds is withdrawn. In addition, this license will terminate immediately without notice from Oracle if you fail to comply with any provision of this license. Upon termination, you must cease use of or destroy the Specification.
"Licensor Name Space" means the public class or interface declarations whose names begin with "java", "javax", "com.oracle" or their equivalents in any subsequent naming convention adopted by Oracle through the Java Community Process, or any recognized successors or replacements thereof.
No right, title, or interest in or to any trademarks, service marks, or trade names of Oracle or Oracle's licensors is granted hereunder. Oracle, the Oracle logo, Java are trademarks or registered trademarks of Oracle USA, Inc. in the U.S. and other countries.
THE SPECIFICATION IS PROVIDED "AS IS" AND IS EXPERIMENTAL AND MAY CONTAIN DEFECTS OR DEFICIENCIES WHICH CANNOT OR WILL NOT BE CORRECTED BY ORACLE. ORACLE MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of the Specification in any product.
THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. ORACLE MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification.
TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ORACLE OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF THE SPECIFICATION, EVEN IF ORACLE AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
You will hold Oracle (and its licensors) harmless from any claims based on your use of the Specification for any purposes other than the limited right of evaluation as described above, and from any claims that later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license.
If this Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Software and accompanying documentation shall be only as set forth in this license; this is in accordance with 48 C.F.R. 227.7201 through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
You may wish to report any ambiguities, inconsistencies or inaccuracies you may find in connection with your evaluation of the Specification ("Feedback"). To the extent that you provide Oracle with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, and (ii) grant Oracle a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any purpose related to the Specification and future versions, implementations, and test suites thereof.
Any action related to this Agreement will be governed by California law and controlling U.S. federal law. The U.N. Convention for the International Sale of Goods and the choice of law rules of any jurisdiction will not apply.
The Specification is subject to U.S. export control laws and may be subject to export or import regulations in other countries. Licensee agrees to comply strictly with all such laws and regulations and acknowledges that it has the responsibility to obtain such licenses to export, re-export or import as may be required after delivery to Licensee.
This Agreement is the parties' entire agreement relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, conditions, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification to this Agreement will be binding, unless in writing and signed by an authorized representative of each party.