Understanding Annotations in Java


Published on

Published in: Education, Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Understanding Annotations in Java

  1. 1. Java Annotations
  2. 2. History The Java platform has had various ad-hoc annotationmechanisms—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-175in 2002 and approved in September 2004. Annotations became available in the language itself beginningwith version 1.5 of the JDK. A provisional interface for compile-time annotation processing was provided by the apt tool in JDKversion 1.5, and was formalized through JSR-269 and integratedinto the javac compiler in version 1.6.
  3. 3. What is it Annotations do not directly affect program semantics, but theydo affect the way programs are treated by tools and libraries, whichcan in turn affect the semantics of the running program.Annotations can be read from source files, class files, orreflectively at run time. Annotations complement javadoc tags. In general, if themarkup is intended to affect or produce documentation, it shouldprobably be a javadoc tag; otherwise, it should be an annotation.
  4. 4. Built-In Annotations appliedto java code@Deprecated—the @Deprecated annotation indicates that the marked element isdeprecated and should no longer be used. The compiler generates a warningwhenever a program uses a method, class, or field with the @Deprecatedannotation. When an element is deprecated, it should also be documented usingthe 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 alowercase "d" and the annotation starts with an uppercase "D". /** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { }
  5. 5. Built-In Annotations appliedto java code@Override—the @Override annotation informs the compiler thatthe element is meant to override an element declared in asuperclass). While its not required to use this annotation whenoverriding a method, it helps to prevent errors. If a method markedwith @Override fails to correctly override a method in one of itssuperclasses, the compiler generates an error. // mark method as a superclass method // that has been overridden @Override int overriddenMethod() { }
  6. 6. Built-In Annotations appliedto java code@SuppressWarnings—the @SuppressWarnings annotation tells the compiler tosuppress specific warnings that it would otherwise generate.// use a deprecated method and tell compiler not to generate awarning@SuppressWarnings("all", "deprecation", "unchecked","fallthrough", "path", "serial", "finally")In the example below, a deprecated method is used and the compiler wouldnormally generate a warning. In this case, however, the annotation causes thewarning 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. 7. Built-In Annotations appliedto 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).
  8. 8. @Target You can specify a single target using a single value or multipleones using an array.@Target ({ElementType.PACKAGE,ElementType.TYPE,ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.ANNOTATION_TYPE})
  9. 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. 10. Annotation attributesReturn types are restricted to primitives, String, Class, enums, annotations, andarrays 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. 11. RetentionPolicy (CLASS vsRUNTIME)RUNTIME: Annotations are to be recorded in the class file by the compiler andretained 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 neednot be retained by the VM at run time.skaffman (TM)In practice, Im not aware of any use-cases for CLASS. It would only be useful ifyou wanted to read the bytecode programmatically, as opposed to via theclassloader API, but thats a very specialised case, and I dont know why youwouldnt just use RUNTIME.Ironically, CLASS is the default behaviour.
  12. 12. RetentionPolicy.SOURCEThese annotations dont make any sense after the compile hascompleted, so they arent written to the bytecode.Example: @Override, @SuppressWarnings
  13. 13. RetentionPolicy.CLASSIt would only be useful if you wanted to read the bytecodeprogrammatically.
  14. 14. Annotation-based testframeworkTo tie it all together, well build a simple annotation-based testframework. First we need a marker annotation type to indicate that amethod 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. 15. Annotation-based test framework Note that the annotation type declaration is itselfannotated. Such annotations are called meta-annotations. The first (@Retention(RetentionPolicy.RUNTIME))indicates that annotations with this type are to be retained bythe VM so they can be read reflectively at run-time. The second (@Target(ElementType.METHOD))indicates that this annotation type can be used to annotateonly method declarations.
  16. 16. Annotation-based test framework Here is a sample program, some of whose methods areannotated 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. 17. Annotation-based test frameworkimport 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); }