A simpler model for repeating annotations

Alex Buckley alex.buckley at oracle.com
Thu Jan 3 14:04:07 PST 2013


I have updated the spec at

   http://cr.openjdk.java.net/~abuckley/8misc.pdf

to reflect the model below.

Alex

On 12/28/2012 12:17 PM, Alex Buckley wrote:
> Feedback from Java EE architects indicates a strong preference for 100%
> behavioral compatibility for legacy core reflection methods.
>
> Summarizing Mike Keith's comments: 1) getAnnotation(Class) must not
> return one @Foo annotation if multiple @Foo annotations were present in
> source, and 2) getAnnotations() must not return multiple @Foo
> annotations if they present in source.
>
> These requirements imply keeping containment at the heart of
> repeatability. Why? Assume there were no containers, and you could
> simply write:
>
>    @Repeatable @interface Foo {}
>
> such that @Foo @Foo on class A is compiled directly into A.class. This
> scheme would impose high complexity on legacy core reflection methods.
> getAnnotation(Foo.class) would have to read _all_ annotations (declared
> and inherited) to detect multiple @Foo annotations then return null or
> throw an exception. (Remember, returning one of the multiple annotations
> is "wrong".) getAnnotations() would have similar trouble deciding what
> to return if multiple @Foo annotations are found. In essence, the legacy
> core reflection methods are morally incompatible with uncontained
> multiple annotations. The solution is to compile multiple annotations
> with containers, and have the legacy core reflection methods behave
> identically to Java SE 7 (no look through).
>
> To support new reflective clients who understand repeating annotations,
> we can keep the previously-proposed getAnnotations(Class) which looks
> through containers. That is, getAnnotations(Foo.class) returns @Foo @Foo
> because it a) detects that Foo.class is a repeatable annotation type
> with a containing annotation type of FooContainer, then b) looks through
> any @FooContainer present.
>
> It is clear that a repeatable annotation type must still nominate its
> containing annotation type, but the reverse is no longer true. That is,
> the declaration of FooContainer no longer needs to say
> @ContainerFor(Foo.class). This is a direct consequence of dropping look
> through for the legacy core reflection methods. Also, the difficult
> question about calling getAnnotations() on a subclass - should it look
> through an inherited container, or return it? - goes away, as normal
> overriding policy gives good answers.
>
> Here's a simple model that Joe, Joel, and I are happy with:
>
> - @Repeatable(FooContainer.class) on @interface Foo {} causes
>    @Foo @Foo in source to be containerized in the class file.
>    (Rename @ContainedBy to @Repeatable.)
>
> - The rules for a well-formed relationship between Foo and
>    FooContainer remain.
>
> - Core reflection's legacy methods return what's in the class file:
>    - get[Declared]Annotation(Foo.class) returns nothing, like today.
>    - get[Declared]Annotations() returns @FooContainer, like today.
>
> - Core reflection's new typed methods look through containers:
>    - get[Declared]Annotations(Foo.class) returns @Foo @Foo.
>
> - An annotation writer may manually rewrite @FooContainer(...) as
>    @Foo @Foo, and it will be containerized with perfect compatibility.
>
> - Language model's legacy methods follow core reflection:
>    - Element.getAnnotation(Foo.class) returns nothing, like today.
>    - Element[s].get[All]AnnotationMirrors() returns @FooContainer, like
> today
>
> - Language model's new typed method looks through:
>    - Element.getAnnotations(Foo.class) returns @Foo @Foo.
>    - We may add Element.getAnnotationMirrors(TypeElement) in future.
>
> I think the reduced semantic burden for an annotation type owner (no
> more @ContainedFor) and the stronger compatibility story for an
> annotation reader (no look through for legacy methods) are real
> improvements. We will specify and implement the model over the next month.
>
> Alex



More information about the enhanced-metadata-spec-discuss mailing list