JDK-8046108 : JEP 118: Access to Parameter Names at Runtime
  • Type: JEP
  • Component: specification
  • Sub-Component: vm
  • Priority: P4
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 8
  • Submitted: 2011-10-18
  • Updated: 2015-02-13
  • Resolved: 2015-02-13
Related Reports
Relates :  
Description
Summary
-------

Provide a mechanism to easily and reliably retrieve the parameter names
of methods and constructors at runtime via core reflection.


Goals
-----

The primary goal is to improve the readability of code which
currently uses logically redundant annotations to record parameter
names.  A secondary goal is to improve IDE capabilities by making
parameter names more widely available.


Motivation
----------

Java uses positional parameter passing, that is, the first argument in
a method call is passed in as the first parameter, the second argument
in a method call is passed in as the second parameter, and so on.
Many other systems use nominal parameter passing where something like
a set of name:value pairs is passed along instead.  When Java code
interfaces with a nominal parameter passing system, the names of the
parameters from the original Java source are often needed to construct
a proper name:value mapping.  Unfortunately, there is no reliable way
within the existing Java SE APIs to retrieve the parameter names of a
method or constructor.  As a workaround, various APIs have defined
their own "`@ParameterName`" annotations, which leads to very
cluttered looking source code.

Java IDEs can now auto-generate template code for creating a concrete
subtype of an interface or abstract class.  If the source code is
available, the parameter names from the source can be used in the
generated code.  If the parameter name information were reliably
stored in class files, useful names could be generated in more cases.

Depending on the approach taken, the long-standing inability to
determine when the number of parameters in the source code of a method
differs from the number or parameters in the compiled form of the
method may also be remedied.


Description
-----------

The proposed approach is to create an optional new JVM attribute in
version 52.0 class files to store information about the parameters of
a JVM-level method.  That information includes:

  * the source-level name of a parameter, if any
  * modifiers of the parameter, if any

A parameter of a method or constructor in a class file might *not*
have any corresponding parameter in the source code.  For example,

  * As an implementation choice, `javac` prepends two synthetic
    parameters to `enum` constructors to allow the compiler to pass in
    name and ordinal information.  Other compilers, including `javac`
    implementations in different releases, are free to use another
    implementation technique to pass along this information.

  * The constructors for anonymous inner classes generally have another
    parameter prepended to the constructor's argument list to allow the
    outer this information to be passed along.  However, anonymous inner
    class constructors in a static context, such as a `static` initializer
    block, need not have such a parameter.

Given the availability of this information, core reflection could then
offer a `java.lang.reflect.Parameter` class to allow retrieval of this
information.  A method to return an array of `Parameter` objects would
be defined in `java.lang.reflect.Executable`, which is a common
superclass of `Method` and `Constructor`.  More direct modeling of
parameter information is preferable to continued indirect modeling as
found in `Method.getParameterTypes` and
`Method.getParameterAnnotations` where the behavior of synthetic
parameters is not well defined.

To avoid introducing unnecessary compatibility restrictions, a
distinction should be made between parameter names available for
informative purposes only and parameters names which are being
provided as an public interface of the method or constructor.  An
annotation is a good candidate to concisely indicate whether or not
particular parameter names are serving as an exported interface.


Alternatives
------------

The design is not finalized, but alternatives include storing the name
information in parameter annotations synthesized by the compiler.  The
trigger to indicate those parameter annotation should be synthesized
could be the presences of an annotation on the class or interface or
even a *meta*annotation on the annotation type of a annotation found
on a class or interface.


Testing
-------

Assuming the general approach in the description section, much of the
implementation would fall into the area of the mostly implicit compiler
specification, that is, the specification of how a Java compiler
translates Java source code into class files (or other executable
output format).  With the source code to class file mapping being
under test, there is a natural match to the coverage areas of JCK
tests, but to be covered under the JCK, some governing Java SE
specification is needed.

For a given design, it is relatively straightforward to use
annotation processors to generate different code samples spanning the
space of variables to be tested.


Risks and Assumptions
---------------------

By introducing a new JVM attribute, the coordination costs of this
change rise considerably since tools which consume class files, from
`pack200` to the JVM itself, need to be updated to handle the new
attribute properly.

Multiple IDE support during the development of JDK 8 would help
validate the operation of this feature.


Dependences
-----------

In JDK components, fully implementing this feature requires
coordinated compiler, libraries, and JVM changes.

Impact
------
  - Compatibility: By default, the names of parameters should *not* be
  added to the compatibility burden of a method or constructor.
  - Performance/scalability: The performance of `javac` should be
  tracked to verify a performance regression is not introduced.