Java注解简单例子

前言

为什么突然想起来注解呢?今天上午同事遇到一个和注解相关的问题,JSP页面传值到后台后(其实前后端并不分离),但是在POJO类上的校验注解值不满足的条件下也通过了,让我给帮忙看看。因为其他组的同事相同的通用代码并没有这个问题,而且对注解的处理是封装在框架中的,所以一开始便排除了问题在后台思路,转向页面传值去调查。虽然最后找到原因是因为没有清空Eclipse的.class文件重新编译,但是感觉已经对之前学过的注解部分的知识生疏了。刚好今天没加班,就赶紧复习一下。

本想在网上找两篇文章回忆一下,但是好像例子写得都不完整。刚好前段时间刚买了一本《Java编程思想》,就赶紧翻开看了一下,一直记得书里给出的例子也是数据库字段注解相关的。

相关概念及原理

参见 ==> 《Java编程思想》第二十章<注解>。

四个元注解:

  • @Target
  • @Retention
  • @Document
  • @Inherited

注解主要是用户按自己的需求来实现。

一个简单的例子

先创建两个注解,@Digits 和 @NotEmpty,用来注解属性是否满足给定条件。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 zhulongkun20@163.com
* @since 2019-05-14 21:42
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Digits {
public int maxLength();

public int fraction() default 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 zhulongkun20@163.com
* @since 2019-05-14 21:47
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmpty {
}

定义一个处理类处理自定义注解:(主要利用反射机制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.Annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
* <p>
* 处理自定义注解
* </p>
*
* @author zhulongkun20@163.com
* @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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.Annotation;

/**
* <p>
* 自定义注解测试类
* </p>
*
* @author zhulongkun20@163.com
* @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);
}
}