Spec update for repeatable/containing relationship

Alex Buckley alex.buckley at oracle.com
Fri Sep 21 11:48:03 PDT 2012

On 9/21/2012 6:47 AM, Paul Benedict wrote:
> (1) "An annotation type TC is the containing annotation type of T if all
> of the following are true ... Any methods declared by TC other than
> value() have a default value."
> Shouldn't a compile error be emitted if this case fails? If I code a
> container annotation but forget defaults on other methods, I think an
> error should occur. I didn't see a line in the spec that explicitly
> stated this behavior, but it would be helpful to developers.

Yes, a compile-time error should and will be emitted. There are strict 
rules about what a well-formed containing annotation type looks like. If 
a prospective repeatable annotation type T has a meta-annotation 
@ContainedBy(TC.class), but TC doesn't look like a well-formed 
containing annotation type (e.g. TC has a blah() method without a 
default), then TC is not in fact the containing annotation type of T. TC 
is a pretender. Then from page 4:

"It is a compile-time error if an annotation type T is (meta-)annotated 
with an @ContainedBy annotation whose value element indicates a type 
other than the containing annotation type of T."

So write T.java and TC.java, and try to compile T.java; it will give an 
error. Try to compile TC.java; it will give an error too, because of:

"It is a compile-time error if an annotation type TC is (meta-)annotated 
with an @ContainerFor annotation whose value element indicates the type 
T, but TC is not the containing annotation type of T."

> (2) In regards to this paragraph: "@ContainerFor supports the Java SE
> platform reflection API in differentiating automatically-generated
> container annotations from legacy annotations which served as idiomatic
> containers prior to Java SE 8."
> I think this paragraph is incorrect regarding (a)
> automatically-generated container annotations and (b) legacy
> annotations. For repeatability to exist at all, a pairing of
> @ContainerFor and @ContainedBy annotation types must exist at compile
> time. So this isn't about "legacy" code, and the pairing doesn't seem to
> provide any room for the container to be "automatically-generated".

In 2007, say, someone declared type Foo and an idiomatic container type 
FooContainer and wrote @FooContainer(value={@Foo(1), at Foo(2)}) on a 
class. The resulting ClassFile will continue to work and be reflectable 
in Java SE 8. But with no "opt-in" via @ContainedBy on Foo and 
@ContainerFor on FooContainer, there is no change in behavior of 
AnnotatedElement methods. For example, get[Declared]Annotations() will 
still return {@FooContainer(..)}. This is the legacy code story.

If in 2013 the annotation type author "opts in", then app authors can 
rewrite @FooContainer(value={@Foo(1), at Foo(2)}) to @Foo(1) @Foo(2) and 
get @FooContainer generated automatically. 2013-era consumers get find 
@Foo annotations directly via get[Declared]Annotations(Foo.class). 
2007-era consumers can still do 
get[Declared]Annotation(FooContainer.class) and inspect the value element.

The introductory text in Chapter 1 will end up as a note in the JLS, so 
if you find it unclear, please suggest an alternative.


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