了解Java注解(@Annotation)
前言
为什么突然想起来注解呢?今天上午同事遇到一个和注解相关的问题,JSP页面传值到后台后(其实前后端并不分离),但是在POJO类上的校验注解值不满足的条件下也通过了,让我给帮忙看看。因为其他组的同事相同的通用代码并没有这个问题,而且对注解的处理是封装在框架中的,所以一开始便排除了问题在后台思路,转向页面传值去调查。虽然最后找到原因是因为没有清空Eclipse的.class文件重新编译,但是感觉已经对之前学过的注解部分的知识生疏了。刚好今天没加班,就赶紧复习一下。
本想在网上找两篇文章回忆一下,但是好像例子写得都不完整。刚好前段时间刚买了一本《Java编程思想》,就赶紧翻开看了一下,一直记得书里给出的例子也是数据库字段注解相关的。
相关概念及原理
参见 ==> 《Java编程思想》第二十章<注解>。
四个元注解:
- @Target
- @Retention
- @Document
- Inherited
注解主要是用户按自己的需求来实现。
一个简单的例子
先创建两个注解,@Digits和@NotEmpty,用来注解属性是否满足给定条件。
代码如下:
package com.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* 标注一个字段只能为数字,且最大长度为maxLength,最大小数位为fraction
* 默认没有小数位
* </p>
*
* @author [email protected]
* @since 2019-05-14 21:42
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Digits {
public int maxLength();
public int fraction() default 0;
}
package com.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* 标注一个字段不能为空
* </p>
*
* @author [email protected]
* @since 2019-05-14 21:47
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmpty {
}
定义一个处理类处理自定义注解:(主要利用反射机制)
package com.Annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* <p>
* 处理自定义注解
* </p>
*
* @author [email protected]
* @since 2019-05-14 21:59
*/
public class AnnotationProcesser {
public void process(Table table) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
Class clazz = table.getClass();
if (clazz == null) {
throw new ClassNotFoundException("class not found!");
}
Field[] fields = clazz.getDeclaredFields();
String fieldName;
for (Field field : fields) {
System.out.println("--------------------------");
field.setAccessible(true);
Annotation[] annotations = field.getDeclaredAnnotations();
fieldName = field.getName();
System.out.println("--> info: into " + fieldName);
for (Annotation annotation : annotations) {
System.out.println("--> info: " + annotation.annotationType());
if (annotation instanceof Digits) {
System.out.println("--> info: get @Digits annotation on " + fieldName);
int maxLength = ((Digits) annotation).maxLength();
int annotatedFraction = ((Digits) annotation).fraction();
String[] fraction = String.valueOf(table.getCount()).split("\\.");
if (String.valueOf(table.getCount()).length() > maxLength) {
System.out.println("--> error: maxLength exceed!");
}
if (fraction.length > 1 && fraction[1].length() > annotatedFraction) {
System.out.println("--> error:fraction length exceed!");
} else {
System.out.println("--> info: " + fieldName + " validate success!");
}
} else if (annotation instanceof NotEmpty) {
System.out.println("--> info: get @NotEmpty annotation on " + fieldName);
if (table.getDescription() == null || "".equals(table.getDescription())) {
System.out.println("--> error: empty is not allowed!");
} else {
System.out.println("--> info: " + fieldName + " validate success!");
}
}
}
}
}
}
主测试类:(省略getter和setter)
package com.Annotation;
/**
* <p>
* 自定义注解测试类
* </p>
*
* @author [email protected]
* @since 2019-05-14 21:49
*/
public class Table {
@Digits(maxLength = 6, fraction = 2)
private double count;
@NotEmpty
private String description;
public Table(double count, String description) {
this.count = count;
this.description = description;
}
public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, NoSuchFieldException {
Table testTable1 = new Table(1234567, "description1");
Table testTable2 = new Table(12.001, "description2");
Table testTable3 = new Table(123.01, "description3");
Table testTable4 = new Table(123.01, null);
Table testTable5 = new Table(123.01, "description5");
AnnotationProcesser processer = new AnnotationProcesser();
processer.process(testTable1);
processer.process(testTable2);
processer.process(testTable3);
processer.process(testTable4);
processer.process(testTable5);
}
}