JDK 9 RFR of JDK-8074977: Constructor.getAnnotatedParameterTypes returns wrong value
peter.levart at gmail.com
Sat May 20 21:48:23 UTC 2017
Thanks for explanation.
Regarding your patch. Take a look here:
I just want to point out that the logic could be centralized for
classical and type annotations. What do you think?
On 05/20/2017 11:38 PM, joe darcy wrote:
> Hi Peter,
> On 5/20/2017 11:00 AM, Peter Levart wrote:
>> Hi Joe,
>> So enum classes, anonymous classes and local classes don't have a
>> standard way of passing synthetic/implicit constructor parameters?
> Right; there is no standardized or mandated way for compilers to do
> that. Such details are intentionally outside of what the JLS specifies.
> Since non-static member classes can be referred to and instances
> instantiated from outside of the enclosing class, there has to be a
> standardized linkage model in that case for separate compilation, etc.
> and that is covered in the JLS. This isn't the case for local and
> anonymous classes since there isn't a way to refer to such classes
> from outside of their immediate declaration context. The instances of
> such types can be returned of course and then it is possible for
> people to getClass().getConstructors()... their way into the issue.
>> Do various compilers do it differently than javac?
> IIRC, ecj does compile enum classes differently than javac.
>> It's unfortunate but if # of parameter annotations arrays is less
>> than the # of parameters, Parameter.getAnnotations() may return wrong
>> annotations or throw IndexOutOfBoundException for enums, anonymous
>> and local classes. Can't we do anything for them? At least for code
>> compiled by javac?
>> For example, javac compiles enum classes so that they always prefix
>> constructor source parameters with a pair of (String name, int
>> ordinal, ...) and so do anonymous enum subclasses provided by enum
>> constants (i.e. clazz.isAnonymousClass() &&
>> Non-static local classes are compiled so that constructor source
>> parameters are prefixed with a single parameter (OuterClass
>> outerInstance, ...), while any captured variables follow source
> A wrinkle with local classes is that if they occur in a static
> context, such as a static initializer block, there is no leading outer
> instance parameter.
> This is admittedly not a 100% solution to parameter mismatches and
> annotations; however, it is an improvement over the current state of
> Ideally, the code for something like Parameters.getAnnotations could
> do something like look at the synthetic bit and pair up natural
> parameters with annotations if there was a mismatch in the number of
> parameters and annotations. Unfortunately, the Parameters.isSynthetic
> API wasn't introduced until JDK 8 and that information doesn't have to
> be available.
>> Static local classes are compiled so that constructor source
>> parameters come 1st, followed by any captured variables.
>> Regards, Peter
>> On 05/19/2017 11:31 PM, joe darcy wrote:
>>> Please review the webrev to fix
>>> JDK-8074977: Constructor.getAnnotatedParameterTypes returns
>>> wrong value
>>> To condense a complicated situation, there are cases where the
>>> number of parameters present for a constructor in source code and
>>> the number of parameters present for that constructor in the class
>>> file differ. One of those cases occurs for the constructor of a
>>> non-static member class  where there is a leading parameter to
>>> accept the outer this argument.
>>> Bug JDK-8074977 reports on a situation where the type annotations on
>>> constructor parameters are incorrectly reported. Essentially, an
>>> off-by-one error is the cause since the annotation information is
>>> stored with respect to the number of parameters present in the
>>> source and an additional parameter is present at runtime.
>>> An analogous situation exists for declaration annotations and
>>> constructor parameters, declaration annotations being the
>>> traditional flavor of annotations.
>>> Type annotations and declaration annotations are read using
>>> different APIs so require separate fixes to detect the additional
>>> parameter and make the necessary adjustments in the returned
>>> The regression tests cover both the type annotation reading API and
>>> the two ways of reading declaration annotations on parameters,
>>> calling getParameterAnnotations on the constructor or call
>>> getParameters on the constructor and then calling getAnnotations on
>>> each parameter. The getParameters API was added in JDK 8.
>>> Static member and non-static member classes are used as test cases,
>>> as are constructors with and without generic type information.
More information about the core-libs-dev