每一秒钟的时间都值得铭记

0%

【小剧场】Java注解:斩颜良诛文丑,插标卖首尔

关公举目一望,谓操曰:”吾观颜良,如插标卖首耳!”

Java 注解并不是程序,只是 Java 程序中的一个标识,Java 程序可以通过这个标识进行一些判断,执行不同的计算和流程。

三国演义中,关公说颜良是插标卖首,这个所谓的 其实和 Java 中的注解有异曲同工之意,都是在人或者代码的头上标注一个东西。

现在,我们就用 Java 注解的功能模拟一下关公斩颜良诛文丑的过程吧。

首先,先创建一个 Person 类,该类代表了所有人,这个类的实例对象,可能是关公,也可能是颜良文丑,也可能只是一个普通的小兵。

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
public class Person {

/**
* 是否已死亡
*/
private boolean die = false;

/**
* 是否死亡
*
* @return 是否死亡
*/
public boolean isDie() {
return this.die;
}

/**
* 被杀
*/
public void beKilled() {
this.die = true;
}

/**
* 杀人
*
* @param person 被杀的人
*/
public void killed(Person... persons) {
for (Person person : persons) {
if (person != null) {
person.beKilled();
}
}
}

}

标(注解)

其次,应该创建一个 Java 注解,这个注解也就是关公所谓的 ,可以在这个标上添加姓名属性,这样就可以通过这个 找到对应的角色。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* <p>- @Target(ElementType.FIELD) 该注解只允许在类属性上标注</p>
* <p>- @Retention(RetentionPolicy.RUNTIME) 该注解保留到运行时</p>
* <p>- @Inherited 该注解会被子类继承</p>
* <p>- @Documented 该类会被 javadoc 生成的文档显示出来</p>
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Name {
String value() default "小兵";
}

战场

既然一切准备就绪,那就可以布置战场了,创建一个战争 Java 类表示战场。

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* 关公举目一望,谓操曰:"吾观颜良,如插标卖首耳!"
*/
public class War {
// 战场中的角色
private Person person1 = new Person();
private Person person2 = new Person();
private Person person3 = new Person();
private Person person4 = new Person();
private Person person5 = new Person();
private Person person6 = new Person();

public static void main(String[] args) throws IllegalAccessException {
War war = new War();
war.start();
}

/**
* 战争开始了
*/
public void start() throws IllegalAccessException {
Person 关羽 = findPerson("关羽");
Person 颜良 = findPerson("颜良");
Person 文丑 = findPerson("文丑");
System.out.println();
checkStatus();
if (关羽 != null) {
关羽.killed(颜良, 文丑);
checkStatus();
System.out.println("关羽" + (颜良 == null ? "" : "斩颜良") + (文丑 == null ? "" : "诛文丑"));
}
}

/**
* 通过姓名找到注解标识了姓名的对应角色
*
* @param name 姓名
* @return 注解标识了姓名的对应角色
*/
public Person findPerson(String name) throws IllegalAccessException {
Field[] fields = War.class.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Name.class)) {
Name annotation = field.getAnnotation(Name.class);
if (annotation.value().equals(name)) {
System.out.print(name + "在战场上\t");
return (Person) field.get(this);
}
}
}
System.out.print(name + "不在在战场上\t");
return null;
}

/**
* 检查当前战场上使用注解标注了姓名的角色的生死
*/
public void checkStatus() throws IllegalAccessException {
Field[] fields = War.class.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Name.class)) {
Name annotation = field.getAnnotation(Name.class);
Person person = (Person) field.get(this);
if (person.isDie()) {
System.out.print(annotation.value() + "死了\t");
} else {
System.out.print(annotation.value() + "活着\t");
}
}
}
System.out.println();
}

}

开战

战争开始

模拟战争开始,直接先执行 main 方法。

战争结果:

1
关羽不在在战场上	颜良不在在战场上	文丑不在在战场上	

颜良进入战场

War 类的某个 Person 类型的属性上,注解上 @Name("颜良")注解,标注姓名。

1
2
@Name("颜良")
private Person person4 = new Person();

战争结果:

1
2
关羽不在在战场上	颜良在战场上	文丑不在在战场上	
颜良活着

关羽进入战场

War 类的某个 Person 类型的属性上,注解上 @Name("关羽")注解,标注姓名。

1
2
@Name("关羽")
private Person person6 = new Person();

战争结果:

1
2
3
4
关羽在战场上	颜良在战场上	文丑不在在战场上	
颜良活着 关羽活着
颜良死了 关羽活着
关羽斩颜良

文丑进入战场

War 类的某个 Person 类型的属性上,注解上 @Name("文丑")注解,标注姓名。

1
2
@Name("文丑")
private Person person5 = new Person();

战争结果:

1
2
3
4
关羽在战场上	颜良在战场上	文丑在战场上	
颜良活着 文丑活着 关羽活着
颜良死了 文丑死了 关羽活着
关羽斩颜良诛文丑

战争结束

关公纵马上山,众将尽皆称贺。公献首级于操前。操曰:“将军真神人也!”

在这段 Java 程序中,Java 代码始终没有任何改变,仅仅只是添加了一些注解,最后的运行结果就完全不一样。这就是 Java 注解的功能,虽然本身不是程序代码的一部分,但是却是代码的标识,可以在程序运行的时候,通过这个标识进行一些判断,执行不同的计算和流程。

现在的大部分的 Java 框架,都有基于 Java 注解的使用版本,原理都是一样的。

本身就是在框架中对框架自定义的注解进行了一些程序判断和处理,使用者只需要在一些代码上标识一些注解,程序就可以按照框架的处理逻辑对这些代码进行处理。

Spring、MyBatis、Hibernate 等框架尽皆如此。

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------