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.
Alex
More information about the enhanced-metadata-spec-discuss
mailing list