articles

Home / DeveloperSection / Articles / Annotations in Java: Documented and Inherited Annotation

Annotations in Java: Documented and Inherited Annotation

Jonas Stuart3623 28-May-2016
The Documented Annotation

The Documented annotation indicates that an annotation with this type should be documented by the Javadoc tool. Javadoc is a documentation generator provided as a part of the JDK that helps in generating API documentation in HTML format from Java source code.  As we already know that we use /** … */ for commenting the code. This is a Javadoc comment.

Javadoc defines several tags, such as

·         @author

·         @version

·         @param

·         @return,

·         and so on.

 We use these tags to describe the corresponding elements.

By default, the Javadoc tool includes annotations in the generated document. Applying the @Documented annotation allows Javadoc-like tools to include the annotation type information in the generated documentation. Incidentally, this is a Marker-type annotation because it does not have any members. To understand how this works, add the @Documented annotation to the WorkInProgress and Task annotations we have created pin the previous post (Annotations at Runtime). Now, generate the documentation for the RuntimeAnnotation class by executing the following command on the command prompt:

c:\360\annotaion>javadoc RuntimeAnnotation.java

Executing this javadoc command will generate quite a few HTML files in the current folder. Open the index.html file in your favorite browser and examine the documentation for the ComputeTax method, which uses both annotations.

The Inherited Annotation

When a class is inherited, the subclass inherits all the non-private properties of its superclass. Does this happen in the case of annotations too? In other words, if a class is annotated, are the annotations of the parent class inherited by the subclass?

Let’s look at an example. Suppose we have a class called Shape that implements a few drawing primitives. The Shape class is not yet fully implemented, so we add the @WorkInProgress annotation we have been using so far. We’ll now extend the Shape class to create a Line class. We would naturally expect and want the Line class to inherit the WorkInProgress annotation because this class is yet to be implemented.

Does this happen naturally? No, this inheritance takes place only if the WorkInProgress annotation is annotated with @Inherited.

Program Code
To better understand this concept, let’s look at the program here:
import java.lang.annotation.*;

@WorkInProgress
class Shape {
                     public void drawShape() {
                     }
}
public class drawShape extends Shape {
                     @Override
                     public void drawShape() {
                     }
                     public static void main(String[] args) {
                             Shape shape = new Shape();
                             Class cls = shape.getClass();
                             if (cls.isAnnotationPresent(WorkInProgress.class)) {
                                      System.out.println("Shape class does require some work");                                       WorkInProgress progress = (WorkInProgress) cls
                                                          .getAnnotation(WorkInProgress.class);                                       System.out.println(progress.doSomething());
                             } else {
                                      System.out.println("Shape is fully implemented");
                             }
                             System.out.println();
                             drawShape line = new drawShape();
                             cls = line.getClass();
                             if (cls.isAnnotationPresent(WorkInProgress.class)) {
                                      System.out.println("Line class does require some work");                                        WorkInProgress progress = (WorkInProgress) cls                                                           .getAnnotation(WorkInProgress.class);
                                      System.out.println(progress.doSomething());
                             } else {
                                      System.out.println("Line is fully implemented");
                             }
                             System.out.println();
                     }
}
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface WorkInProgress {
                     String doSomething() default "\tDo what?";
}

Explanation

·   The WorkInProgress annotation defines one property (doSomething) and is annotated with Retention, Documented, and Inherited.

·   The Shape class is annotated with WorkInProgress. The Line class inherits the Shape class, but does not contain an explicit WorkInProgress annotation.

·   In the main method of the Line class, we print the status of annotations by using the reflection mechanism discussed earlier. We create instances of both Shape and Line classes.

·   We obtain the Class instances of both classes by using the getClass method of Object, as used previously. We check whether the annotation is present by calling the isAnnotationPresent method of Class.

·    If the annotation is present, we print the value of doSomething to the user console; otherwise, we print the message that the class is fully implemented.

Output

When we run the program, we see the following output:

Shape class does require some work

                Do what?
Line class does require some work
                 Do what?

From this output, we can clearly see that Line class has inherited the WorkInProgress annotation applied only to its parent class—Shape.

Now, comment out the @Inherited annotation in the declaration of the WorkInProgress annotation.

Run the program and you will see the following output:
Shape class does require some work
              Do what?
Line is fully implemented


The output now indicates that the Line is fully implemented, indicating that it does not have the WorkInProgress annotation in effect. It is assumed that the developer has implemented the Line class without first completing the Shape class—which may be true in some situations.

In general, these annotations are very useful in documenting our code, for compilers to generate appropriate warnings, and for runtime tools to provide better testing of an application.


Updated 20-Dec-2019

Leave Comment

Comments

Liked By