Java编程之Annotation全解析
来源:互联网 发布:淘宝售后申请时间限制 编辑:程序博客网 时间:2024/06/15 03:12
前言
通过本篇的学习可以达到以下目标:
了解Annotation的作用
掌握JDK 1.5中内建的3种Annotation
掌握自定义Annotation的语法及其应用
掌握@Retention,@Target,@Documented,@Inherited注释。
Annotation简介
J2SE5.0提供了很多新的特性。其中一个很重要的特性就是对元数据(Metadata)的支持。在J2SE5.0中,这种元数据称为注释(Annotation).通过使用注释,程序开发人员可以在不改变原有逻辑的情况下,在源文件嵌入一些补充的信息。
Annotation可以用来修饰类,属性,方法,而且Annotation不影响程序运行,无论是否使用Annotation代码都可以正常执行。
java.lang.annotation.Annotation是Annotation的接口,只要是Annotation都必须实现此接口。
此接口定义如下:
public interface Annotation{public Class<? extends Annotation> annotationType();//返回此Annotation的注释类型public boolean equals(Object obj);public int hashCode();String toString();
本篇以后所介绍的系统内建的Annotation和用户自定义的Annotation都是默认实现了此接口。
这里写代码片ext/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlqaXpoaTE5OTUwMTIz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast” alt=”这里写图片描述” title=”” />
@Override
@Override主要是在方法覆写时使用,用于保证方法覆写的正确性。下面介绍此注释的基本使用。
代码如下:
package org.;jz.systemannotation;class Person{ //定义Person类public String getInfo(){ //定义getInfo()方法 return "这是一个Person类。" //返回信息 }}class Student extends Person{ //子类继承父类@Overridepublic String getInfo(){ //覆写父类方法return "这是一个Student类"; }}public class OverrideAnnotationDemo01{public static void main(String[] args){ Person per=new Student(); //通过子类实例化父类对象 System.out.println(per.getInfo()); //输出信息 }}
程序运行结果:
这是一个Student类
以上的程序中的子类Student继承Person类,之后覆写了Person类中的getInfo()方法,程序的运行结果与之前一样,唯一不同的只是在覆写的getInfo()方法前加上了@Override注释,这样做的目的主要是防止用户在覆写方法时将方法定义出错
注意
@Override在使用时只能在方法上应用,而其他元素,如类,属性等上是不能使用此Annotation的。
@Deprecated
@Deprecated注释的主要功能是用来声明一个不建议使用的方法的方法。如果在程序中使用了此方法,则在编译时就出现警告信息。
使用@Deprecated声明一个不建议使用的方法
package org.demo.systemannotation;class Demo{ //定义一个Demo类@Deprecated //声明不建议使用的操作public String getInfo(){ //此方法不建议使用return "这是一个Person类" //返回信息 }}public class DeprecatedAnnotationDemo01{public static void main(String[] args){Demo d=new Demo(); //实例化Demo对象System.out.println(d.getInfo()); //编译时,将出现警告信息 }}
以上的类在getInfo()方法上使用了@Deprecated注释声明,这就表示此方法不建议继续使用,所以在编译时出现了警告。另外与@Override有所区别的是,@Deprecated除了可以在方法上声明外,在类中也可以进行声明。
@SuppressWarnings
@SuppressWarnings注释的主要功能是用来压制警告,例如,之前讲泛型操作时,如果在一个类声明时没有指明泛型,则肯定在编译时产生警告,那么此时就可以使用@SuppressWarnings压制住这种警告。
如下面代码所示:
package org.ljz.systemannotation;@Deprecated //以下操作不建议使用class Demo<T>{ //定义了Demo类,使用泛型 private T var; //定义泛型变量 public T getVar(){ //取得泛型变量的内容 return var;}public void setVar(T var){ //设置泛型变量this.var=var; }}public class SuppressWarningAnnotationDemo02{@SuppressWarnings({"unchecked","deprecation"}) //此时压制两条警告public static void main(String[] args){ Demo d=new Demo //编译时的警告信息将被压制d.setVar("ljz");System.out.println(" 内容: "+d.getVar()); //输出 }}
以上程序同时存在了泛型和不建议使用方法两种警告,但是由于使用了@SuppressWarning注释,所以此时在程序编译时将不会出现任何的警告信息。
以上在压制多个警告时,使用了unchecked和deprecation两种关键字,是以字符串数组的形式设置进行声明的。@SuppressWarnings中的可以压制的警告类型如下表所示:
自定义Annotation
之前已经介绍了3种Java中自建的Annotation,只要通过固定的格式调用即可。接下来我将介绍如何自定义Annotation.
Annotation常用格式
[public] @interface Annotation 名称{
数据类型 变量名称();
}要定义Annotation必须使用@interface的方式进行定义
自定义一个Annotation
package org.ljz.defaultannotation;public @interface MyDefaultAnnotationNoneParam{ //定义Annotation}
使用Annotation
package org.ljz.defaultannotation;@MyDefaultAnnotationNoneParam //使用自定义的Annotationclass Demo{}
以上的Demo类的声明处就使用了之前定义好的MyDefaultAnnotationNoneParam注释
向Annotation中设置内容
package org.ljz.defaultannotation;public @interface MyDefaultAnnotationArrayParam{ //定义Annotationpublic String[] value(0; //接收设置的内容是一个字符串数组}
调用Annotation并设置数组属性
package org.ljz.defaultannotation;@MyDefaultAnnotationArrayParam{value={"name","ljz"})//使用自定义的Annotationclass Demo{}
在以上操作中,所有的内容都是需要用户在调用Annotation时手工设置的。
Retention和RetentionPolicy
在Annotation中,可以使用Retention定义一个Annotation的保存范围。此Annotation的定义如下:
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention{
RetentionPolicy value();
}在以上的Retention定义中存在一个RetentionPolicy的变量,此变量用于指定Annotation的保存范围。
定义在RUNTIME范围有效的Annotation
package org.ljz.retentiondemo;import java.lang.annotion.Retention;import java.lang.annotation.RetentionPolicy;@Retention(value=RetentionPolicy.RUNTIME) //此Annotation在执行时起作用public @interface MyDefaultRetentionAnnotation{public String name() default"ljz"; //只能设置枚举中的取值}
以上定义的Annotion在程序执行时起作用,这是一种比较常见的使用方式,而如果此时将其设置成其他范围,则以后在Annotation的应用中肯定是无法访问到的,要想让Annotion起作用,则必须结合JAVA中的反射机制。
通过反射取得Annotation
范例——取得全部Annotion
为了方便操作,以下程序首先定义了一个类,并在类中的方法上使用了系统内建好的3个Annotation。
定义一个简单类
package org.ljz.reflectannotion;public class SimpleBeanOne{@SuppressWarnings("unchecked") //使用@@SuppressWarnings的Annotation@Deprecated //使用@Deprecated的Annotation@Override //使用@Override的Annotationpublic String toString(){ //覆写toStringreturn "Hello ljz"" //返回信息 }}
以上程序覆写的toString()方法中使用了3个内建的Annotation,要想取得SimpleBeanOne中toString()方法的全部Annotation,则必须首先通过反射找到toString()方法。
取得全部Annotation
package org.ljz.reflectannotation;import java.lang.reflect.Method;public class ReflectDemo01{public static void main(String args[])throws Exception{//所有异常抛出Class<?> c=null; //取得Class实例c=Class.forName("org.ljz.reflectannotion.SimpleBeanOne")Method toM=c.getMethod("toString");//取得toString()方法Annotation an[]=toM.getAnnotation();//取得全部的Annotationfor(Annotation a: an){ //foreach输出System.out.println(a); //直接输出信息 } } }
程序运行结果:
@java.lang.Deprecated()
SimpleBeanOne的toString()方法上虽然使用了3个Annotation注释,但是最后真正的得到的只能是一个,这是因为只有Deprecated使用了RUNTIME的方式声明,所以只有它可以取得。
- Java编程之Annotation全解析
- Java中的Annotation解析之二(1)
- Java中的Annotation解析
- Java 中的Annotation全攻略
- Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)
- Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)
- Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)
- Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)
- Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)
- java事务全解析(七)--像Spring一样使用Transactional注解(Annotation)
- Java Annotation之应用篇 – 运行期动态解析annotation (3)
- Java Annotation之应用篇 – 运行期动态解析annotation
- Spring实例解析之Annotation
- Java中的Annotation解析(一)
- Java中的Annotation解析(二)
- java annotation注解的解析
- Java 注解Annotation使用解析
- java学习之annotation
- JVM (PART VIII)HotSpot的各种收集器和常见组合
- 设计模式的基础——类图以及类与类之间的关系
- dedecms判断栏目是否有下级菜单
- 【hibernate】配置hbm2ddl.auto属性
- Elasticsearch 5 Ik+pinyin分词配置详解
- Java编程之Annotation全解析
- gtk图形界面编程day02
- Scala(3)-Traits
- C语言随机获取小写字母
- Scipy安装
- 关于结构体成员的直接赋值
- 数字图像处理——边缘检测
- 统计字符串中字符的频数
- 开发环境搭建