[Records] Component annotations not propagated when explicit canonical constructor is given
Jorn Vernee
jorn.vernee at oracle.com
Mon Jan 20 12:15:26 UTC 2020
Hi,
I remember this issue coming up before. Looks like there was a fix
targeted at JDK 15: https://bugs.openjdk.java.net/browse/JDK-8236597
Jorn
On 20/01/2020 09:36, Gunnar Morling wrote:
> Thanks for your reply!
>
>> If a canonical ctor / accessor is explicitly specified, the annos on the declaration are used instead.
> That's where things are still unclear for me, it seems contradictory
> to "sounds like incorrect behavior to me" above. To make things more
> concrete, here's an example:
>
> public class RecordAnnos {
> public static void main(String... args) {
> System.out.println(Arrays.toString(Foo.class.getConstructors()[0].getParameters()[0].getAnnotations()));
> System.out.println(Arrays.toString(Bar.class.getConstructors()[0].getParameters()[0].getAnnotations()));
> }
>
> public static record Foo (@Deprecated String foo) {}
>
> public static record Bar (@Deprecated String bar) {
> public Bar {}
> }
> }
>
> Running this prints:
>
> java --enable-preview --source 14 RecordAnnos.java
> [@java.lang.Deprecated(forRemoval=false, since="")]
> []
>
> Whereas I hoped it'd print this:
>
> [@java.lang.Deprecated(forRemoval=false, since="")]
> [@java.lang.Deprecated(forRemoval=false, since="")]
>
> In case an explicit canonical constructor is declared without the
> formal parameter list, there's no way to specify any annotations on
> the parameters. So shouldn't those from the components be applied?
> With the current behaviour, if I want to declare any annotation for
> the constructor itself, I need to repeat all annotations from the
> components on the annotations of a fully manually implemented
> constructor:
>
> public static record Bar (@Deprecated String bar) {
> @Deprecated
> public Bar(@Deprecated String bar) {
> this.bar = bar;
> }
> }
>
> Note that @Deprecated is just used here to make the example
> self-contained; my actual use case is about Bean Validation constraint
> annotations.
>
> Thanks,
>
> --Gunnar
>
> Am Mo., 20. Jan. 2020 um 01:32 Uhr schrieb Brian Goetz <brian.goetz at oracle.com>:
>> This sounds like incorrect behavior to me. The way it should work is:
>>
>> - A declaration annotation is applicable to a record component if it has no @Target meta-anno, or its target includes one or more of PARAMETER, FIELD, METHOD, RECORD_COMPONENT.
>> - For _each_ of the applicable types present, the anno is pushed down to the corresponding _implicit_ { ctor parameter, field, accessor method, record component }.
>> - If multiple applicable types are present, it is pushed down to all of them.
>> - If a canonical ctor / accessor is explicitly specified, the annos on the declaration are used instead.
>>
>>
>>
>>
>> On 1/19/2020 4:14 PM, Gunnar Morling wrote:
>>
>> Hi,
>>
>> I'm observing the following behaviour around annotations on record
>> components, using JDK 14 b32. I'm putting an annotation to a record
>> component:
>>
>> public record Person(@NotNull String name) {}
>>
>> In this case the @NotNull annotation is propagated to the
>> corresponding parameter of the generated constructor, from where I can
>> obtain it using reflection. This is not the case though when I
>> explicitly declare the canonical constructor:
>>
>> public record Person(@NotNull String name) {
>> public Person {
>> // ...
>> }
>> }
>>
>> In this case the annotation isn't propagated, and it won't be
>> retrievable from that constructor's parameter via reflection.
>>
>> Is this behaviour intended or is it a bug actually? I lean towards the
>> latter, as I don't explicitly define the parameter in the constructor,
>> so I'd expect the annotations given on the component to still be
>> propagated.
>>
>> If it *is* intended, it'd make my use case a bit more complex, as I'd
>> want to be able to put other annotations to the canonical constructor
>> *itself*, while still getting all the component annotations propagated
>> to its parameters.
>>
>> Thanks a lot,
>>
>> --Gunnar
>>
>>
More information about the amber-dev
mailing list