KEMBAR78
Understanding Annotations in Java | PPT
Java Annotations
History
     The Java platform has had various ad-hoc annotation
mechanisms—for example, the transient modifier, or the
@deprecated javadoc tag.
     The general purpose annotation (also known as metadata)
facility was introduced to the Java Community Process as JSR-175
in 2002 and approved in September 2004.
     Annotations became available in the language itself beginning
with version 1.5 of the JDK. A provisional interface for compile-
time annotation processing was provided by the apt tool in JDK
version 1.5, and was formalized through JSR-269 and integrated
into the javac compiler in version 1.6.
What is it
     Annotations do not directly affect program semantics, but they
do affect the way programs are treated by tools and libraries, which
can in turn affect the semantics of the running program.
Annotations can be read from source files, class files, or
reflectively at run time.
     Annotations complement javadoc tags. In general, if the
markup is intended to affect or produce documentation, it should
probably be a javadoc tag; otherwise, it should be an annotation.
Built-In Annotations applied
to java code
@Deprecated—the @Deprecated annotation indicates that the marked element is
deprecated and should no longer be used. The compiler generates a warning
whenever a program uses a method, class, or field with the @Deprecated
annotation. When an element is deprecated, it should also be documented using
the Javadoc @deprecated tag, as shown in the following example. The use of the
"@" symbol in both Javadoc comments and in annotations is not coincidental —
they are related conceptually. Also, note that the Javadoc tag starts with a
lowercase "d" and the annotation starts with an uppercase "D".

 /**
   * @deprecated
   * explanation of why it was deprecated
   */
  @Deprecated
  static void deprecatedMethod() { }
Built-In Annotations applied
to java code
@Override—the @Override annotation informs the compiler that
the element is meant to override an element declared in a
superclass). While it's not required to use this annotation when
overriding a method, it helps to prevent errors. If a method marked
with @Override fails to correctly override a method in one of its
superclasses, the compiler generates an error.

 // mark method as a superclass method
  // that has been overridden
  @Override
  int overriddenMethod() { }
Built-In Annotations applied
to java code
@SuppressWarnings—the @SuppressWarnings annotation tells the compiler to
suppress specific warnings that it would otherwise generate.
// use a deprecated method and tell compiler not to generate a
warning@SuppressWarnings("all", "deprecation", "unchecked",
"fallthrough", "path", "serial", "finally")
In the example below, a deprecated method is used and the compiler would
normally generate a warning. In this case, however, the annotation causes the
warning to be suppressed.
 // use a deprecated method and tell
 // compiler not to generate a warning
 @SuppressWarnings("deprecation")
 void useDeprecatedMethod() {
    // deprecation warning - suppressed
    objectOne.deprecatedMethod();
 }
Built-In Annotations applied
to other annotations
•   @Target - Marks another annotation to restrict what kind of
    java elements the annotation may be applied to.
•   @Retention - Specifies how the marked annotation is stored --
    Whether in code only, compiled into the class, or available at
    runtime through reflection.
•   @Documented - Marks another annotation for inclusion in the
    documentation.
•   @Inherited - Marks another annotation to be inherited to
    subclasses of annotated class (by default annotations are not
    inherited to subclasses).
@Target
 You can specify a single target using a single value or multiple
ones using an array.

@Target ({
ElementType.PACKAGE,
ElementType.TYPE,
ElementType.CONSTRUCTOR,
ElementType.METHOD,
ElementType.PARAMETER,
ElementType.FIELD,
ElementType.LOCAL_VARIABLE,
ElementType.ANNOTATION_TYPE
})
@RetentionPolicy
•   RetentionPolicy.SOURCE retains an annotation only in
    the source file and discards it during compilation.
•   RetentionPolicy.CLASS stores the annotation in the .class
    file but does not make it available during runtime.
•   RetentionPolicy.RUNTIME stores the annotation in the
    .class file and also makes it available during runtime.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TryThis {
 String [] value();
}
Annotation attributes
Return types are restricted to primitives, String, Class, enums, annotations, and
arrays of the preceding types. Methods can have default values.
Here is an example annotation type declaration:

/**
 * Describes the Request-For-Enhancement(RFE) that led
 * to the presence of the annotated API element.
 */
public @interface RequestForEnhancement {
   int id();
   String synopsis();
   String engineer() default "[unassigned]";
   String date(); default "[unimplemented]";
  String[] text();
}
RetentionPolicy (CLASS vs
RUNTIME)
RUNTIME: Annotations are to be recorded in the class file by the compiler and
retained by the VM at run time, so they may be read reflectively.
CLASS: Annotations are to be recorded in the class file by the compiler but need
not be retained by the VM at run time.

skaffman (TM)
In practice, I'm not aware of any use-cases for CLASS. It would only be useful if
you wanted to read the bytecode programmatically, as opposed to via the
classloader API, but that's a very specialised case, and I don't know why you
wouldn't just use RUNTIME.
Ironically, CLASS is the default behaviour.
RetentionPolicy.SOURCE

These annotations don't make any sense after the compile has
completed, so they aren't written to the bytecode.

Example: @Override, @SuppressWarnings
RetentionPolicy.CLASS

It would only be useful if you wanted to read the bytecode
programmatically.
Annotation-based test
framework
To tie it all together, we'll build a simple annotation-based test
framework. First we need a marker annotation type to indicate that a
method is a test method, and should be run by the testing tool:

import java.lang.annotation.*;
/**
 * Indicates that the annotated method is a test method.
 * This annotation should be used only on parameterless static methods.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test { }
Annotation-based test
               framework
    Note that the annotation type declaration is itself
annotated. Such annotations are called meta-annotations.
    The first (@Retention(RetentionPolicy.RUNTIME))
indicates that annotations with this type are to be retained by
the VM so they can be read reflectively at run-time.
    The second (@Target(ElementType.METHOD))
indicates that this annotation type can be used to annotate
only method declarations.
Annotation-based test
             framework
   Here is a sample program, some of whose methods are
annotated with the above interface:
   public class Foo {
   @Test public static void m1() { }
     public static void m2() { }
   @Test public static void m3() { }
     public static void m4() { }
   @Test public static void m5() { }
   }
Annotation-based test
                   framework
import java.lang.reflect.*;
public class RunTests {
  public static void main(String[] args) throws Exception {
    int passed = 0, failed = 0;
    for (Method m : Class.forName(args[0]).getMethods()) {
      if (m.isAnnotationPresent(Test.class)) {
         try {
           m.invoke(null);
           passed++;
         } catch (Throwable ex) {
           System.out.printf("Test %s failed: %s %n", m, ex.getCause());
           failed++;
         }
      }
    }
    System.out.printf("Passed: %d, Failed %d%n", passed, failed);
  }
Understanding Annotations in Java

Understanding Annotations in Java

  • 1.
  • 2.
    History The Java platform has had various ad-hoc annotation mechanisms—for example, the transient modifier, or the @deprecated javadoc tag. The general purpose annotation (also known as metadata) facility was introduced to the Java Community Process as JSR-175 in 2002 and approved in September 2004. Annotations became available in the language itself beginning with version 1.5 of the JDK. A provisional interface for compile- time annotation processing was provided by the apt tool in JDK version 1.5, and was formalized through JSR-269 and integrated into the javac compiler in version 1.6.
  • 3.
    What is it Annotations do not directly affect program semantics, but they do affect the way programs are treated by tools and libraries, which can in turn affect the semantics of the running program. Annotations can be read from source files, class files, or reflectively at run time. Annotations complement javadoc tags. In general, if the markup is intended to affect or produce documentation, it should probably be a javadoc tag; otherwise, it should be an annotation.
  • 4.
    Built-In Annotations applied tojava code @Deprecated—the @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag, as shown in the following example. The use of the "@" symbol in both Javadoc comments and in annotations is not coincidental — they are related conceptually. Also, note that the Javadoc tag starts with a lowercase "d" and the annotation starts with an uppercase "D". /** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { }
  • 5.
    Built-In Annotations applied tojava code @Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass). While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error. // mark method as a superclass method // that has been overridden @Override int overriddenMethod() { }
  • 6.
    Built-In Annotations applied tojava code @SuppressWarnings—the @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. // use a deprecated method and tell compiler not to generate a warning@SuppressWarnings("all", "deprecation", "unchecked", "fallthrough", "path", "serial", "finally") In the example below, a deprecated method is used and the compiler would normally generate a warning. In this case, however, the annotation causes the warning to be suppressed. // use a deprecated method and tell // compiler not to generate a warning @SuppressWarnings("deprecation") void useDeprecatedMethod() { // deprecation warning - suppressed objectOne.deprecatedMethod(); }
  • 7.
    Built-In Annotations applied toother annotations • @Target - Marks another annotation to restrict what kind of java elements the annotation may be applied to. • @Retention - Specifies how the marked annotation is stored -- Whether in code only, compiled into the class, or available at runtime through reflection. • @Documented - Marks another annotation for inclusion in the documentation. • @Inherited - Marks another annotation to be inherited to subclasses of annotated class (by default annotations are not inherited to subclasses).
  • 8.
    @Target You canspecify a single target using a single value or multiple ones using an array. @Target ({ ElementType.PACKAGE, ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.ANNOTATION_TYPE })
  • 9.
    @RetentionPolicy • RetentionPolicy.SOURCE retains an annotation only in the source file and discards it during compilation. • RetentionPolicy.CLASS stores the annotation in the .class file but does not make it available during runtime. • RetentionPolicy.RUNTIME stores the annotation in the .class file and also makes it available during runtime. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TryThis { String [] value(); }
  • 10.
    Annotation attributes Return typesare restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. Methods can have default values. Here is an example annotation type declaration: /** * Describes the Request-For-Enhancement(RFE) that led * to the presence of the annotated API element. */ public @interface RequestForEnhancement { int id(); String synopsis(); String engineer() default "[unassigned]"; String date(); default "[unimplemented]"; String[] text(); }
  • 11.
    RetentionPolicy (CLASS vs RUNTIME) RUNTIME:Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively. CLASS: Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. skaffman (TM) In practice, I'm not aware of any use-cases for CLASS. It would only be useful if you wanted to read the bytecode programmatically, as opposed to via the classloader API, but that's a very specialised case, and I don't know why you wouldn't just use RUNTIME. Ironically, CLASS is the default behaviour.
  • 12.
    RetentionPolicy.SOURCE These annotations don'tmake any sense after the compile has completed, so they aren't written to the bytecode. Example: @Override, @SuppressWarnings
  • 13.
    RetentionPolicy.CLASS It would onlybe useful if you wanted to read the bytecode programmatically.
  • 14.
    Annotation-based test framework To tieit all together, we'll build a simple annotation-based test framework. First we need a marker annotation type to indicate that a method is a test method, and should be run by the testing tool: import java.lang.annotation.*; /** * Indicates that the annotated method is a test method. * This annotation should be used only on parameterless static methods. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { }
  • 15.
    Annotation-based test framework Note that the annotation type declaration is itself annotated. Such annotations are called meta-annotations. The first (@Retention(RetentionPolicy.RUNTIME)) indicates that annotations with this type are to be retained by the VM so they can be read reflectively at run-time. The second (@Target(ElementType.METHOD)) indicates that this annotation type can be used to annotate only method declarations.
  • 16.
    Annotation-based test framework Here is a sample program, some of whose methods are annotated with the above interface: public class Foo { @Test public static void m1() { } public static void m2() { } @Test public static void m3() { } public static void m4() { } @Test public static void m5() { } }
  • 17.
    Annotation-based test framework import java.lang.reflect.*; public class RunTests { public static void main(String[] args) throws Exception { int passed = 0, failed = 0; for (Method m : Class.forName(args[0]).getMethods()) { if (m.isAnnotationPresent(Test.class)) { try { m.invoke(null); passed++; } catch (Throwable ex) { System.out.printf("Test %s failed: %s %n", m, ex.getCause()); failed++; } } } System.out.printf("Passed: %d, Failed %d%n", passed, failed); }