JDK 9 RFR of JDK-8074977: Constructor.getAnnotatedParameterTypes returns wrong value

Peter Levart peter.levart at gmail.com
Sat May 20 21:48:23 UTC 2017

Hi Joe,

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?

Regards, Peter

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() && 
>> clazz.getSuperclass().isEnum())
>> 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 
>> parameters
> 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 
> affairs.
> 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.
> Cheers,
> -Joe
>> Static local classes are compiled so that constructor source 
>> parameters come 1st, followed by any captured variables.
>> etc...
>> Regards, Peter
>> On 05/19/2017 11:31 PM, joe darcy wrote:
>>> Hello,
>>> Please review the webrev to fix
>>>     JDK-8074977: Constructor.getAnnotatedParameterTypes returns 
>>> wrong value
>>> http://cr.openjdk.java.net/~darcy/8074977.3/
>>> 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 [1] 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 
>>> information.
>>> 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.
>>> Thanks,
>>> -Joe
>>> [1] 
>>> https://blogs.oracle.com/darcy/nested,-inner,-member,-and-top-level-classes

More information about the core-libs-dev mailing list