Thanks Ken, your response was well worth the read.
lloyd
On Oct 24, 2008, at 9:36 AM, Ken Cavanaugh wrote:
> Lloyd Chambers wrote:
>>
>> Thanks everyone for the very interesting followup!
>>
>> I've read the posts, etc, but it's still unclear to me whether
>> @Override is legal or not on a sub-interface (in JDK 1.6). My
>> original intent was to have the compiler enforce the claim: "This
>> method MUST exist in a super-interface".
>>
>> Implementation doesn't matter for my intended purpose.
>>
>> - Every @Configured that is a PropertyBag needs to redeclare the
>> getProperty() method so it can add annnotations to it;
>> - No @Configured should have the getProperty() method unless it
>> IS_A PropertyBag.
>>
>> We have this case not just for PropertyBag, but for several other
>> interfaces as well eg (Named).
>>
>> ======== Annnotations and interface hierarchies ==========
>>
>> What does it mean to have an interface hierarchy with successive re-
>> declarations of the same method?
> Good question. I've done a lot a annotation processing lately,
> mainly for JMXA. The first thing to remember
> is that any AnnotatedElement has at most one instance of any
> annotation (because AnnotatedElement.getAnnotation
> can only return one annotation of any type, mirroring the fact that
> multiple declarations of the same
> annotation on the same element are rejected by the compiler).
> getAnnotation will return the value of the annotation on
> the element on which it is called, if present. For classes, if the
> annotation definition contains the @Inherited
> meta-annotation, getAnnotation will return the first instance of the
> annotation found in following the superclass
> inheritance chain. Interface inheritance has NO effect on this (see
> the javadoc for java.lang.annotation.Inherited),
> and this can definitely be a problem.
>
> For my own purposes (since I want to see annotations on interfaces
> as well as classes), I wrote some simple utilities
> to represent the class and interface inheritance as a graph, and
> then use a reversed post-order traversal of the
> graph to determine the search order when looking for annotations.
> That way I can see annotations on interfaces
> as well as classes.
>> -- Do the annotations accumulate when programs go to use them?
>> (Depends on how the API is used I think)
> No, but you can find all of them by exploring the class hierarchy if
> needed (or yes, you can write code that
> effectively accumulates annotations if you wish, depending on how
> you view my answer :-)).
>> -- Only one annotation of a given type is possible on each target
>> in a given class/interface. But sub-interfaces can add another
>> annotation of the same type. How does this interact with the API,
>> and what is it supposed to mean for a system like HK2?
> It completely depends on the implementation. The most
> straightforward case is to just call getAnnotation on the class,
> in which case (for inherited annotations) you walk up the superclass
> chain until you get an annotation, or end at Object.
> But any implementation is free (as in my case) to do whatever it
> wants to. That's why the @Inherited meta-annotation is
> not so useful: it really means NOTHING outside of the context of a
> particular implementation of annotation processing.
>
> I can see two useful models here:
> If an annotation acts like a constraint, it probably makes sense to
> accumulate annotation information and act on all of it
> In most cases, probably what you want is simply the most specific
> annotation of a given type. @Inherited does this in simple cases,
> but more complex cases require directly writing code to analyze the
> class hierarchy.
> There are probably other models that I haven't thought of that make
> sense.
>>
>> Example: (http://en.wikipedia.org/wiki/Lichen)
>>
>> How many @GrowableStuff annotations exist on Lichen?
>> How many @Override annotations?
>> And is this legal in JDK 6 or not?
> Not sure about @Override, it sounds like (from other discussions)
> that it is legal in JDK 6 (but not in JDK 5).
> The other annotations should be legal in any case.
>>
>> public interface Growable {
>> @GrowableStuff(...) public void grow();
>> }
>>
>> public interface Mycobiont extends Growable {
>> @Override @GrowableStuff(...) @MycobiontStuff public void grow();
>> }
>>
>> public interface Phycobiont extends Growable {
>> @Override @GrowableStuff(...) @PhycobiontStuff public void grow();
>> }
>>
>> public interface Lichen extends Mycobiont, Phycobiont {
>> @Override @GrowableStuff(...) @LichenStuff public void grow();
>> }
> What I THINK will happen for the methods (I need to check this, it's
> important for JMXA as well)
> is that you will get the annotations on the Method object for the
> method as defined in a
> particular class. In your example,
>
> Lichen.class.getDeclaredMethod( "grow" ).getAnnotations()
>
> should return the @GrowableStuff(...) and @LichenStuff annotations
> (@Override is annotated
> with source retention, so the compiler will discard it).
>
> On the other hand,
>
> Phycobiont.class.getDeclaratedMethod( "grow" ).getAnnotations()
>
> should return @GrowableStuff( ... ) (with different info than on
> Lichen) and @PhycobiontStuff.
>
> Ken.