6.10 Setting Up Inheritance in Annotations
A classic case of creating a
problematic situation comes up with inheritance.
Consider a class that has been deprecated, and set to be phased
out of use. It's possible (and quite easy) for a programmer who isn't paying
attention to extend that class, use it all over the place, and avoid the
deprecated warnings that would have shown up if the superclass, which
is deprecated, was used. The problem is that a class that is deprecated
doesn't pass on this deprecation status to its subclassescreating a
potential for real problems in your code. Suddenly you have thousands of
references to a non-deprecated class, but you can't remove the deprecated
class because it's the superclass of all the referenced objects! Using
the Inherited meta-annotation can help out here.
6.10.1 How do I do that?
Let's take another example of a status, represented by an annotation,
which should be inherited: the InProgress indicator. Example 6-13
shows a simple class that uses this annotation.
Example 6-13. Using the InProgress annotation
package com.oreilly.tiger.ch06;Example 6-14 is another simple class, which extends Super.
import java.io.IOException;
import java.io.PrintStream;
@InProgress
public class Super {
public void print(PrintStream out) throws IOException {
out.println("Super printing...");
}
}
Example 6-14. Extending the Super class
package com.oreilly.tiger.ch06;If you generate the Javadoc for these classes, you'll see, as shown in
import java.io.IOException;
import java.io.PrintStream;
public class Sub extends Super {
public void print(PrintStream out) throws IOException {
out.println("Sub printing...");
}
}
Figure 6-3, that Super is correctly noted as being in progress.
Figure 6-3. Super, with an InProgress annotation

have this indicator (see Figure 6-4).The problem is that the InProgress annotation type isn't inherited; this
use-case shows that's probably a mistake. To correct it, make the following
change to InProgress:
@DocumentedRecompile your classes, and re-generate your Javadoc. I'll bet you're
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface InProgress { }
expecting to see another figure, with the Sub class pulled up, flagged as
being in progress. Well, that's what I was expecting toobut it doesn't
work yet. Presumably this will be fixed before things go final, but hopefully
you've at least gotten the idea about what should happen.It's also worth noting that while the documentation feature isn't working
correctly, reflection is. You can indeed determine that Sub is in progress
through reflectionit just doesn't show up in the Javadoc. To see how
reflection works with annotations, see Reflecting on Annotations.
Figure 6-4. Sub, without an annotation

6.10.2 What about...
...interfaces? Annotations marked as Inherited only apply to subclasses,
so implementing a method with annotations will not result in the annotations
being inherited.Additionally, if you override a method from a superclass, you don't inherit
that specific method's annotations. Only the annotations on the superclass
itself are inherited, and those by the subclass as a whole.
|