Java Custom Annotations Example
What is Annotation?
Annotations are nothing but meta-data added to the Java Elements. Annotations define a java type exactly similar to Classes,Enums,Interfaces and they can be applied to several Java Elements.
Annotations are interfaces, so you don't implement anything in them.
Annotation is defined using @ along with interface keyword.There are two meta annotations required to create custom annotationas shown in example below.
@Target(ElementType.CLASS)
@Retention(RetentionPolicy.CLASS)
public @interface Author
{
String name();
}
The Meta-Annotations that would be covered in the forthcoming sections are,
@Target: It specifies to which java elements annotation can be applied. Different java elements to which annotations can be applied are: FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE, ANNOTATION_TYPE, PACKAGE.
If we don't fine any @Target , you can use this annotation anywhere in your classes by default.
@Retention :This meta annotation specifies till what time annotations can be retained and when they can be discarded
1. SOURCE :Retain annotation in source file and discard them at compile time
2. CLASS : Retain annotation in class file and discard them at run time
3. RUNTIME : Retain annotation at runtime and never discard them. This will allow us to use Java reflections later on.
The retention annotation indicates where and how long annotations of this type will be retained. This annotation has three options source, class and runtime. If the retention option selected is source, the annotation is discarded post compilation. Examples of such annotation types are @Override and @SuppressWarnings. The next option is class, the annotation is discarded during class load. The last option is the runtime. The annotation information marked using this option is never discarded. The annotation should be available for reflection at runtime.
How annotations are retrieved or read?
Annoations onece defined and used in some class we can read them using reflection package methods like getAnnotations().We have to first obtain the refrence to the class which contains or uses the Annotaions then we cane write code like given below
Class classObj = MyAnnotedClass.class;
Annotation[] annotations = classObj.getAnnotations();
for (Annotation annotation : annotations) {
}
Built-In Annotations
Built-In Annotations that are applied to java code
@Override
@SuppressWarnings
@Deprecated
Built-In Annotations that are applied to other annotations
@Target
@Retention
@Inherited
Indicate that an annotation type is automatically inherited. If user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class’s superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached.
@Documented
By default, the annotation and related information does not appear in the class javadoc. A marker annotation @Documented in provided to cause the annotation related information to be added in the class javadoc.
@SafeVarargs
Introduced in java 7, this annotation ensures that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter. Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.
@Repeatable
By default, an annotation is applied on a java element only once. But, by any requirement, you have to apply a annotation more than once, then use @Repeatable annotation on your new annotation.
@FunctionalInterface
This annotation is used to mark an interface as functional interface which are introduced in java 8.
Restriction on Annotation
https://github.com/dima767/inspektr/blob/master/inspektr-audit/src/main/java/com/github/inspektr/audit/AuditTrailManagementAspect.java
http://www.importnew.com/10294.html
http://idlebrains.org/tutorials/java-tutorials/how-annotations-work-java/
What is Annotation?
Annotations are nothing but meta-data added to the Java Elements. Annotations define a java type exactly similar to Classes,Enums,Interfaces and they can be applied to several Java Elements.
Annotations are interfaces, so you don't implement anything in them.
- 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.
Annotation is defined using @ along with interface keyword.There are two meta annotations required to create custom annotationas shown in example below.
@Target(ElementType.CLASS)
@Retention(RetentionPolicy.CLASS)
public @interface Author
{
String name();
}
The Meta-Annotations that would be covered in the forthcoming sections are,
@Target: It specifies to which java elements annotation can be applied. Different java elements to which annotations can be applied are: FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE, ANNOTATION_TYPE, PACKAGE.
If we don't fine any @Target , you can use this annotation anywhere in your classes by default.
@Retention :This meta annotation specifies till what time annotations can be retained and when they can be discarded
1. SOURCE :Retain annotation in source file and discard them at compile time
2. CLASS : Retain annotation in class file and discard them at run time
3. RUNTIME : Retain annotation at runtime and never discard them. This will allow us to use Java reflections later on.
The retention annotation indicates where and how long annotations of this type will be retained. This annotation has three options source, class and runtime. If the retention option selected is source, the annotation is discarded post compilation. Examples of such annotation types are @Override and @SuppressWarnings. The next option is class, the annotation is discarded during class load. The last option is the runtime. The annotation information marked using this option is never discarded. The annotation should be available for reflection at runtime.
How annotations are retrieved or read?
Annoations onece defined and used in some class we can read them using reflection package methods like getAnnotations().We have to first obtain the refrence to the class which contains or uses the Annotaions then we cane write code like given below
Class classObj = MyAnnotedClass.class;
Annotation[] annotations = classObj.getAnnotations();
for (Annotation annotation : annotations) {
}
Built-In Annotations
Built-In Annotations that are applied to java code
@Override
@SuppressWarnings
@Deprecated
Built-In Annotations that are applied to other annotations
@Target
@Retention
@Inherited
Indicate that an annotation type is automatically inherited. If user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class’s superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached.
@Documented
By default, the annotation and related information does not appear in the class javadoc. A marker annotation @Documented in provided to cause the annotation related information to be added in the class javadoc.
@SafeVarargs
Introduced in java 7, this annotation ensures that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter. Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.
@Repeatable
By default, an annotation is applied on a java element only once. But, by any requirement, you have to apply a annotation more than once, then use @Repeatable annotation on your new annotation.
@FunctionalInterface
This annotation is used to mark an interface as functional interface which are introduced in java 8.
Restriction on Annotation
Other important things to remember while creating custom annotations are listed below:
- Each method declaration defines an element of the annotation type.
- Method declarations must not have any parameters or a throws clause.
- Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
- Methods can have default values.
https://github.com/dima767/inspektr/blob/master/inspektr-audit/src/main/java/com/github/inspektr/audit/AuditTrailManagementAspect.java
http://www.importnew.com/10294.html
http://idlebrains.org/tutorials/java-tutorials/how-annotations-work-java/
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }Annotations are only metadata and they do not contain any business logic. Annotations only provide some information about the attribute (class/method/package/field) on which it is defined. Consumer is a piece of code which reads this information and then performs necessary logic.
Annotations only support primitives, string and enumerations. All attributes of annotations are defined as methods and default values can also be provided
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface Todo { public enum Priority {LOW, MEDIUM, HIGH} public enum Status {STARTED, NOT_STARTED} String author() default "Yash"; Priority priority() default Priority.LOW; Status status() default Status.NOT_STARTED; }
If we have only one attribute inside an annotation, it should be named “value” and can be used without attribute name while using it.
@interface Author{ String value(); } @Author("Yashwant") public void someMethod() { }
Class businessLogicClass = BusinessLogic.class; for(Method method : businessLogicClass.getMethods()) { Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class); if(todoAnnotation != null) { System.out.println(" Method Name : " + method.getName()); System.out.println(" Author : " + todoAnnotation.author()); System.out.println(" Priority : " + todoAnnotation.priority()); System.out.println(" Status : " + todoAnnotation.status()); } }http://www.mkyong.com/java/java-custom-annotations-example/
Class<TestExample> obj = TestExample.class;
// Process @TesterInfo
if (obj.isAnnotationPresent(TesterInfo.class)) {
Annotation annotation = obj.getAnnotation(TesterInfo.class);
TesterInfo testerInfo = (TesterInfo) annotation;
System.out.printf("%nPriority :%s", testerInfo.priority());
System.out.printf("%nCreatedBy :%s", testerInfo.createdBy());
System.out.printf("%nTags :");
int tagLength = testerInfo.tags().length;
for (String tag : testerInfo.tags()) {
if (tagLength > 1) {
System.out.print(tag + ", ");
} else {
System.out.print(tag);
}
tagLength--;
}
System.out.printf("%nLastModified :%s%n%n", testerInfo.lastModified());
}
// Process @Test
for (Method method : obj.getDeclaredMethods()) {
// if method is annotated with @Test
if (method.isAnnotationPresent(Test.class)) {
Annotation annotation = method.getAnnotation(Test.class);
Test test = (Test) annotation;
// if enabled = true (default)
if (test.enabled()) {
try {
method.invoke(obj.newInstance());
System.out.printf("%s - Test '%s' - passed %n", ++count, method.getName());
passed++;
} catch (Throwable ex) {
System.out.printf("%s - Test '%s' - failed: %s %n", ++count, method.getName(), ex.getCause());
failed++;
}
} else {
System.out.printf("%s - Test '%s' - ignored%n", ++count, method.getName());
ignore++;
}
}
}
http://ifeve.com/java-annotations/
http://www.javacodegeeks.com/2012/11/java-annotations-tutorial-with-custom-annotation.html
References
Annotations
Complete Java Annotations Tutorial
http://www.javacodegeeks.com/2012/11/java-annotations-tutorial-with-custom-annotation.html
@Documented |
11 | @Target (ElementType.METHOD) |
12 | @Inherited |
13 | @Retention (RetentionPolicy.RUNTIME) |
14 | public @interface MethodInfo{ |
15 | String author() default 'Pankaj' ; |
16 | String date(); |
17 | int revision() default 1 ; |
18 | String comments(); |
19 | } |
- 注解方法不能带有参数;
- 注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;
- 注解方法可以有默认值;
- 注解本身能够包含元注解,元注解被用来注解其它注解。
1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
2. @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。
3. @Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
4.@Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME。
10 | for (Method method : AnnotationParsing. class |
11 | .getClassLoader() |
12 | .loadClass(( 'com.journaldev.annotations.AnnotationExample' )) |
13 | .getMethods()) { |
14 | // checks if MethodInfo annotation is present for the method |
15 | if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo. class )) { |
16 | try { |
17 | // iterates all the annotations available in the method |
18 | for (Annotation anno : method.getDeclaredAnnotations()) { |
19 | System.out.println( 'Annotation in Method ' '+ method + ' ' : ' + anno); |
20 | } |
21 | MethodInfo methodAnno = method.getAnnotation(MethodInfo. class ); |
22 | if (methodAnno.revision() == 1 ) { |
23 | System.out.println( 'Method with revision no 1 = ' + method); |
24 | } |
25 |
26 | } catch (Throwable ex) { |
27 | ex.printStackTrace(); |
28 | } |
29 | } |
30 | } |
31 | } catch (SecurityException | ClassNotFoundException e) { |
32 | e.printStackTrace(); |
33 | } |
34 | } |
References
Annotations
Complete Java Annotations Tutorial