学习Java注解时,曾提到:所有的注解都将继承java.lang.annotation.Annotation接口,无法再继承其他的类或实现
当真正深入使用注解时,发现系统学习Annotation接口是非常必要的
例如,Annotation接口定义了自己的equals()、hashCode()和toString()方法,且对这些方法的实现有着自己的一套规则
若不按照这些规则重写相关方法,则可能导致注解对象的使用存在问题
Annotation接口的重要方法
仔细阅读Annotation接口的源码,类注释如下,关键信息:所有的注解都将继承Annotation接口
The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type. Also note that this interface does not itself define an annotation type.
Annotation接口定义了自己的方法,甚至包括equals()、hashCode()和toString()方法
![](https://img-blog.csdnimg.cn/img_convert/c0b989c847b6de5a982bcb87dabb9b4c.png)
上述三个方法,在Object类中也存在,但是二者对这三个方法的约束有所差异
toString()方法
Object类的toString()方法,返回一个可以表示对象的字符串,默认实现:class_name@16进制_hashcode
![](https://img-blog.csdnimg.cn/img_convert/bf4453acb1eea3ad8d88dcf3f9643be7.png)
Annotation接口的toString()方法,返回一个表示注解的字符
一般采用@annotation_class_name(memver1=value1,member2=value2, ...)的格式
使用Guice自定义绑定注解的方式,定义含有多个元素的@MultiMember
![](https://img-blog.csdnimg.cn/img_convert/8e68e9a0e705cb055b97b66b982a1a09.png)
@MultiMember的toString()方法的实际代码如下:
![](https://img-blog.csdnimg.cn/img_convert/539d7cf433eb41413e3c1842cca1574d.png)
以@MultiMember(name="lucy", version=9)以的方式使用@MultiMember,Guice在程序运行出错时,将打印的注解信息为:@org.sunrise.binding.MultiMemberBinding(name=lucy, version=9)
equals()方法
Object规定equals()方法用于判断两个对象是否等价,要求其实现具备5大特性:自反性、对称性、传递性、一致性、非空性
Object的equals()方法实现,采用了对象相等的最高标准 —— 同一对象
Annotation接口的equals()方法,用于判断两个注解类型的对象是否相等
equals()方法返回true:指定对象(obj)与当前对象(this)属于相同的注解类型,且两个对象中的所有元素(成员变量)分别对应相等,
如何比较元素是否相等?
基本数据类型,除float、double外,使用 x == y进行判断
float、double类型,需要通过包装类型进行判断,例如,double类型,使用Double.valueOf(x).equals(Double.valueOf(y))进行判断
String、Class、枚举、注解类型,使用x.equals(y)进行判断
Array类型,使用 Arrays.equals(x, y)进行判断
annotationType()方法
Object类中,没有annotationType()方法
Annotation接口的annotationType()方法,用于返回注解的类型
注解实际也是一个接口,可以定义类实现注解。这些实现类的annotationType()方法,一般返回所实现的注解的类型
implements
很多场景,我们只是定义注解,然后在某些地方直接使用注解。
学习如何自定义注解,可以按照接口的定义方式理解注解的定义方式。例如,注解的元素声明与接口中方法声明的对照学习
除此之外,我们对注解是一个接口的体会并不深
本小节将介绍如何implements注解,一方面可以学习如何按照Annotation中的要求implements注解,另一方面有利于体会注解是一个接口这一事实
不完善的注解实现
3.1.1 IDE自动引入需要重写的方法
创建MultiMemberImpl类,作为@MultiMember的实现类
这时,IDE会提示有需要重写的方法
![](https://img-blog.csdnimg.cn/img_convert/fd31de4d426b27600bbce0b36f51cfa5.png)
通过IDE引入这些需要重写的方法,形成的代码如下:
![](https://img-blog.csdnimg.cn/img_convert/cb067bcfcf717a1aa321894d5cbacfa3.png)
因此, IDE为MultiMemberImpl自动添加了name()和version()方法,以实现方法重写
同时,根据继承关系可知,MultiMemberImpl还需要重写Annotation接口中的方法