关公举目一望,谓操曰:”吾观颜良,如插标卖首耳!”
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;
public boolean isDie() { return this.die; }
public void beKilled() { this.die = true; }
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
|
@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 ? "" : "诛文丑")); } }
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 等框架尽皆如此。