http://bethecoder.com/applications/tutorials/java-annotations-class-and-runtime-retention-policy.html
Class and Runtime Retention Policy
Annotations with Retention Policy CLASS and RUNTIME are accessible from class byte code.We need to use a byte code manipulation library to access the Annotations available in byte code.This example uses ASM to fetch Annotations from class byte code.
Annotations with Retention Policy CLASS,
package com.bethecoder.tutorials.annotations.retention2; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Permitted types for annotation attributes * * 1. primitive type * 2. String * 3. Class * 4. annotation * 5. enumeration * 6. 1-dimensional arrays */ @Retention ( RetentionPolicy.CLASS ) @Target ( ElementType.TYPE ) public @interface Author { String name () default "admin" ; String creationDate () ; }
Annotations with Retention Policy RUNTIME,
package com.bethecoder.tutorials.annotations.retention2; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Permitted types for annotation attributes * * 1. primitive type * 2. String * 3. Class * 4. annotation * 5. enumeration * 6. 1-dimensional arrays */ @Retention ( RetentionPolicy.RUNTIME ) @Target ( ElementType.TYPE ) public @interface VersionHistory { String [] value () ; }
Its usage is shown below,
package com.bethecoder.tutorials.annotations.retention2; @Author ( name= "BTC" , creationDate= "01/01/2500" ) @VersionHistory ({ "1.0" , "2.0" , "3.0" }) public class Source { private int fieldOne; private String fieldTwo; public Source ( int fieldOne, String fieldTwo ) { super () ; this .fieldOne = fieldOne; this .fieldTwo = fieldTwo; } public int getFieldOne () { return fieldOne; } public void setFieldOne ( int fieldOne ) { this .fieldOne = fieldOne; } public String getFieldTwo () { return fieldTwo; } public void setFieldTwo ( String fieldTwo ) { this .fieldTwo = fieldTwo; } }
The ASM Tree API code to access Annotations is shown below,
package com.bethecoder.tutorials.annotations.retention2; import java.util.List; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; public class Test { /** * @param args */ public static void main ( String [] args ) throws Exception { //ASM Tree API ClassNode cn = new ClassNode () ; //Read the class byte code from stream ClassReader cr = new ClassReader ( ClassLoader.getSystemResourceAsStream ( "com/bethecoder/tutorials/annotations/retention2/Source.class" )) ; cr.accept ( cn, 0 ) ; System.out.println ( "Class Name : " + cn.name ) ; System.out.println ( "Source File : " + cn.sourceFile ) ; //Annotations with RetentionPolicy.CLASS //@Retention(RetentionPolicy.CLASS) System.out.println ( "\n==Invisible Annotations==" ) ; printAnnotation ( cn.invisibleAnnotations ) ; //Annotations with RetentionPolicy.RUNTIME //@Retention(RetentionPolicy.RUNTIME) System.out.println ( "\n==Visible Annotations==" ) ; printAnnotation ( cn.visibleAnnotations ) ; } private static void printAnnotation ( List annotationList ) { if ( annotationList != null && !annotationList.isEmpty ()) { AnnotationNode anNode = null ; for ( Object annotation : annotationList ) { anNode = ( AnnotationNode ) annotation; System.out.println ( "Annotation Descriptor : " + anNode.desc ) ; System.out.println ( "Annotation attribute pairs : " + anNode.values ) ; } } else { System.out.println ( "No annotations found.." ) ; } } }
It gives the following output,
Class Name : com/bethecoder/tutorials/annotations/retention2/Source
Source File : Source.java
==Invisible Annotations==
Annotation Descriptor : Lcom/bethecoder/tutorials/annotations/retention2/Author;
Annotation attribute pairs : [name, BTC, creationDate, 01/01/2500]
==Visible Annotations==
Annotation Descriptor : Lcom/bethecoder/tutorials/annotations/retention2/VersionHistory;
Annotation attribute pairs : [value, [1.0, 2.0, 3.0]]