这一次我们来看看注解的Annotation接口。
首先我们要知道什么是注解,注解这个特性是java5引入进来的,主要是在代码上附带上元数据或标记。这样的做法使代码与一些框架的配置项很好的结合起来,且增加了代码的可读性,Hibernate注解就是非常成功的使用。
Java本身为我们提供了三个注解,他们分别是
java,lang.Override
@Override注解说明该方法覆盖了父类的某个方法,在编译时编译器将对该方法进行检查,如果出现拼写错误,或父类并没有这个方法将报错。
java,lang.Deprecated
@Deprecated注解说明该类、方法、成员变量已经不再建议使用了,一般IDE会将@Deprecated的类、方法、成员变量划掉以提示开发者。
java,lang.SuppressWarnings
@SuppressWarnings可以消除编译器的warning,在你非常确定一个类、方法、变量的warning是可以忽略的时候,你可以使用这个注解。
那么我们以下面这个超简单的例子来说明注解是如何使用的:
@Deprecated public class Test { }
我们可以看到我们为Test类添加了@Deprecated注解,于是Test被IDE划掉了。在Java中注解可以反射成Annotation的对象,而我们获取Annotation的办法则是通过一个AnnotatedElement接口来实现。Class正好实现了这个接口。
在AnnotatedElement中一共有
<T extends Annotation> T getAnnotation(Class<T> annotationType);
boolean isAnnotationPresent(Class<? extends Annotation> annotationType);
Annotation[] getAnnotations();
Annotation[] getDeclaredAnnotations();
这四个方法。
首先我们就以刚刚那个例子为例,来试一下如何获取类的@Deprecated注解对象
@Deprecated public class Test { public static void main(String[] args) { Annotation aOverride = new Test().getClass().getAnnotation(Override.class); System.out.println("new Test().getClass().getAnnotation(Override.class)=" + aOverride); //输出new Test().getClass().getAnnotation(Override.class)=null Annotation aDeprecated = new Test().getClass().getAnnotation(Deprecated.class); System.out.println("new Test().getClass().getAnnotation(Deprecated.class)=" + aDeprecated); //输出new Test().getClass().getAnnotation(Deprecated.class)=@java.lang.Deprecated() } }
我们可以看到的确把这个Annotation给获取出来了,但我们发现我们必须预先知道注解的类型才能获取出来,那么有没有办法来判断将要获取的注解是什么类型呢?一个简单的思路就是通过调用
boolean isAnnotationPresent(Class<? extends Annotation> annotationType);
方法以及if-else来判断我们的类使用了哪一个注解,从而调用对应的getAnnotation方法
@Deprecated public class Test { public static void main(String[] args) { Class<? extends Test> t = new Test().getClass(); Annotation a; if (t.isAnnotationPresent(Override.class)) { a = t.getAnnotation(Override.class); } else if (t.isAnnotationPresent(Deprecated.class)) { a = t.getAnnotation(Deprecated.class); } else if (t.isAnnotationPresent(SuppressWarnings.class)) { a = t.getAnnotation(SuppressWarnings.class); } else { a = null; } System.out.println("a=" + a);//输出a=@java.lang.Deprecated() } }
在控制台我们可以看到,的确获取了正确的注解对象了。但有时我们需要自行添加一些新的注解,如果按照这样的思路,不断添加if-else语句显然是不科学的。那怎么才能在不知道注解类型的情况下获注解对象呢?AnnotatedElement接口中的getAnnotations方法就解决了这个问题,我们还是以上面的那个例子为例,获取一下@Deprecated注解的对象
@Deprecated public class Test { public static void main(String[] args) { Class<? extends Test> t = new Test().getClass(); Annotation[] arg = t.getAnnotations(); System.out.println("arg.length=" + arg.length);//arg.length=1 Annotation a = arg[0]; System.out.println("a=" + a);//a=@java.lang.Deprecated() } }
在控制台我们看到我们在不知道注解类型的情况下获取了注解对象。
getAnnotations()方法可以帮我们在不知道注解类型的情况下获取在类、方法、变量上面的全部注解。在这我们自定义一个注解为@MyAnnotation
@Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String hello(); }
然后注解到我们的Test类上,然后调用getAnnotations方法
@Deprecated @MyAnnotation(hello="你好") public class Test { public static void main(String[] args) { Class<? extends Test> t = new Test().getClass(); Annotation[] arg = t.getAnnotations(); System.out.println("arg.length=" + arg.length);//arg.length=2 for (Annotation a : arg) { System.out.println(" a=" + a); } } }
我们看到两个注解的对象都被我们获取回来了。
仔细观察的朋友可能会发现在AnnotatedElement类中还有一个getDeclaredAnnotations方法,它的返回值与getAnnotations方法是一样的。那他们有些什么区别的呢?
首先我们要知道注解是可以继承的,就是说子类会继承父类的一些注解(该注解在定义时一定要声明为@Inherited,而且方法和变量上的注解不一定能继承)。我们再编写一个Test2类来给Test继承
@MyAnnotation(hello="你好") class Test2 { } @Deprecated public class Test extends Test2{ public static void main(String[] args) { Class<? extends Test> t = new Test().getClass(); Annotation[] ta = t.getAnnotations(); System.out.println("ta.length=" + ta.length); for (Annotation temp: ta){ System.out.println(temp); } Annotation[] tda = t.getDeclaredAnnotations(); System.out.println("tda.length=" + tda.length); for (Annotation temp: tda){ System.out.println(temp); } } }
我们可以看到在控制台里面tda只输出了一条信息,而ta则有两条。就是因为tda屏蔽了由Test2继承而来的@Deprecated。
在我们大体知道如何利用反射机制获取注解对象之后,我们来看看Annotation接口都为我们提供了哪些方法。
首先我们来看看equals和hash方法
@MyAnnotation(hello="你好") public class Test{ public static void main(String[] args) { Annotation a1 = new Test().getClass().getAnnotation(MyAnnotation.class); Annotation a2 = new Test2().getClass().getAnnotation(MyAnnotation.class); boolean temp = a1.equals(a2); System.out.println(temp + "=Test的MyAnnotation==Test2的MyAnnotation"); System.out.println("a1=" + a1.hashCode()); System.out.println("a2=" + a2.hashCode()); } } @MyAnnotation(hello="你好") class Test2 { }
从控制台我们发现Annotation对象有这样的规则,只要是相同的注解,不管它注解的是哪个类都将指向同一个空间,这一点有些类似字符串常量的机制。
而Annotation的另一个方法toSting()则只返回Annotation对象的类以及其成员变量,它并没有像Object的成员变量那样既显示出hashcode又显示出对象的类型。
最后在Annotation类里,还有一个比较实用的方法
Class<? extends Annotation> annotationType();
这个方法可以返回当前注解对象的注解类型,这样我们就可以在不知道注解类型的情况下反射获取注解对象并获取出它的类型来进行一些特别的处理了。
@MyAnnotation(hello="你好") public class Test{ public static void main(String[] args) { Annotation a = new Test().getClass().getAnnotations()[0]; Class<? extends Annotation> c = a.annotationType(); System.out.println(c); } }
从上面的这个例子我们可以看到,我们在不知道不了解注解类型的情况情况下取得了注解的对象以及注解类型。
通过这个方法我们就可以进行许多方便有效的注解反射操作了。
相关推荐
Java annotation 什么是java annotation?annotation 的7种标注类型。nnotation提供了一条与程序元素关联任何信息或者任何元数据(metadata...annotation类型是一种接口,能够通过java反射API的方式提供对其信息的访问。
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
赠送jar包:javax.annotation-api-1.2.jar; 赠送原API文档:javax.annotation-api-1.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom;...
赠送jar包:javax.annotation-api-1.3.2.jar; 赠送原API文档:javax.annotation-api-1.3.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.3.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-...
Spring Annotation
@androidx.annotation.NonNull 缺失的兼容、androidx.annotation兼容包
javax.annotation-3.0.jar javax.annotation-3.0.jar javax.annotation-3.0.jar
这里面包涵了需要用Hibernate Annotation时,所需要的所有jar包! 现在我们公司在做web项目的时候,已经不用*.hbm.xml这种映射文件了,都是用Annotation(注解)方式来完成实体与表之间的映射关系,这样看起来比用...
Annotation核心技术Annotation核心技术Annotation核心技术Annotation核心技术Annotation核心技术Annotation核心技术
Annotation权威资料 Annotation权威资料 Annotation权威资料 Annotation权威资料 Annotation权威资料 Annotation权威资料Annotation权威资料
hibernate annotation hibernate3
hibernate annotation中文文档
赠送jar包:geronimo-annotation_1.0_spec-1.1.1.jar; 赠送原API文档:geronimo-annotation_1.0_spec-1.1.1-javadoc.jar; 赠送源代码:geronimo-annotation_1.0_spec-1.1.1-sources.jar; 赠送Maven依赖信息文件:...
annotation详解 讲解annotation的使用 教程
hibernate 注解 annotation 教程
JDK9及以上版本没有javax.annotation-api-***.jar包 ,无法使用注解:@Resource JDK新特性,高版本JDK没有自带的javax(java扩展包)了。或者是使用的JDK不完整。 下载javax.annotation.jar包,导入到lib文件夹下,...
androidx-annotation-1.0.0.jar
Java 5 annotation 学习笔记Java 5 annotation 学习笔记Java 5 annotation 学习笔记
Java-Annotation使用大全 Java-Annotation使用大全 Java-Annotation使用大全