Java Annotations – Retention

Consider a Java annotation:

public @interface AnAnnotaton {

}

A class with this annotation applied on it:

@AnAnnotaton
class AnAnnotatedClass{
 
}

And a test which checks if this annotation is present on a class:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import java.lang.annotation.Annotation;
import org.junit.Test;

public class AnAnnotationTest {
 
 
 @Test
 public void testAnAnnotation() throws Exception {
  AnAnnotatedClass anAnnotatedClass = new AnAnnotatedClass();
  Annotation[] annotationsOnClass = anAnnotatedClass.getClass().getAnnotations();
  assertThat(annotationsOnClass.length, is(1));
 }

}

Sounds reasonable right, one would expect the above test to pass since the class does have an annotation of AnAnnotation on it.

But, this test fails, and the reason is…

a missing meta annotation(@Retention) on the annotation which indicates how long the annotation is to be retained, if the annotation above is changed as follows, the test would work as expected.

@Retention(RetentionPolicy.RUNTIME)
public @interface AnAnnotaton {

}

So what does @Retention do – to quote from the Javadoc:

Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS

there are three different retention policies:
1. SOURCE – where the annotations are removed by the compiler
2. CLASS – Annotations are present in the bytecode, but are not present at runtime and hence not available when trying to reflectively determine if a class has the annotation.
3. RUNTIME – Annotations are retained in the byte code and is available at runtime and hence can be reflectively found on a class.

This is the reason why when the annotation definition was changed to include @Retention(RetentionPolicy.RUNTIME), the test now runs through.

Something basic, but easy to miss out.

Reference: Java Annotations – Retention from our JCG partner Biju Kunjummen at the all and sundry blog.

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

Leave a Reply


seven − 4 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books