Strict checking of correctness of containing type by Core Reflection
Alex Buckley
alex.buckley at oracle.com
Thu Mar 7 16:48:01 PST 2013
Hi Joel,
Yes, the compile-time definition of "containing annotation type" TC has
constraints on TC's value element, non-value elements, retention,
applicability (@Target), documentation, and inheritance.
I agree with your sharp observation that, for an instance of TC at
run-time, it is possible for getAnnotationsByType(T.class) to ignore
TC's non-value elements, retention, and documentation. The first two are
inherently correct at run-time, while the third is insignificant.
I think TC's applicability is insignificant too. At run-time, it could
be inapplicable to the element on which reflection finds @TC(value=...),
but the fact that @TC is found means TC (and actually T also) must have
been applicable there at compile-time. I think it's fine for
getAnnotationsByType(T.class) to unpack the packed @T's which were
repeated legally in the source program.
Finally, inheritance. If T and TC are both @Inherited, and @T @T is
applied to a class X, then removing @Inherited from TC would presumably
cause getAnnotationsByType(T.class) to not see @TC on subclass Y and so
not expose @T @T. That's a potentially serious behavioral
incompatibility for clients reflecting over Y. Should we stop the client
with an AnnotationFormatError? Maybe not. It is rather appealing to
check only the presence of a T[]-typed value element.
Alex
On 3/7/2013 4:38 AM, Joel Borggrén-Franck wrote:
> Hi Experts,
>
> The latest 8misc.pdf currently define 6 criteria for a type TC to be the
> a containing type for T, further T is repeatable if(f) T is annotated
> with a @Repeatable annotation indicating TC, the containing type for T.
>
> The javadoc for AnnotatedElement says that the new methods
> get*AnnotationsByType(Class) detects if the argument is a repeatable
> annotation type and in that case does the look through to find repeated
> instances. My interpretation of the wording "*repeatable annotation
> type* (JLS 9.6)" from the method javadoc is that the @Repeatable
> meta-annotation indicating TC _and_ all 6 correctness criteria on TC
> should be checked and enforced at runtime. If one or more fails an
> AnnotationFormatError should be thrown.
>
> This is however not strictly necessary in order to unpack the container.
> You can unpack checking only that:
>
> * @Repeatable on T indicates a TC
>
> * If you find an instance of TC then:
>
> ** T and TC have suitable targets for the AnnotatedElement your are
> reflecting on (this is currently missing in the RI)
>
> ** TC has an T-array valued value() element
>
>
> - You don't need to check @Documented.
>
> - The VM should have enforced that all elements on TC either have a
> default or an explicit value, so you can get by without verifying that
> all non-value() elements have a default.
>
> - Retention will by necessity be RUNTIME for both otherwise either the
> container or the repeated instances will be invisible.
>
> - Inheritance works the same way.
>
> I can see pros and cons with being lenient and not enforcing all 6
> correctness criteria, for example I'm not a big fan of the idea of
> throwing an error for a missing @documented. On the other hand there
> might be some surprises lurking in not bing strict on inheritance.
>
> So how strict should we be? Comments much appreciated!
>
> cheers
> /Joel
More information about the enhanced-metadata-spec-discuss
mailing list