Annotation

来源:互联网 发布:阿里妈妈淘宝客采集器 编辑:程序博客网 时间:2024/05/20 16:10

一:简介

使用注释,可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。Annotation可以用来修饰类、属性、方法,而且Annotation不影响程序运行,无论是否使用Annotation,代码都可以正常执行。


二:各个Annotation使用

1、@Override

表示这个方法是覆写父类中的方法:

范例1:

package haizhu.com;class Person{public String getInfo(){return "这是一个Person类";}}class Student extends Person{@Overridepublic String getInfo(){return "这是一个Student类";}}public class AnnotationDemo01 {public static void main(String[] args) {Person per = new Student();System.out.println(per.getInfo());}}

如果声明了@Override,则使用IDE进行编辑的时候,如果继承的这个类中没有这个歌方法,就会进行出错提醒,如果使用记事本编辑,则会在编译的时候进行出错提醒。


2、@Deprecated

表示这个方法不建议使用:

范例2:

package haizhu.com;class Person{@Deprecatedpublic String getInfo(){return "这是一个Person类";}}public class AnnotationDemo02 {public static void main(String[] args) {Person per = new Person();System.out.println(per.getInfo());}}
在使用Person的实例调用getInfo()方法的时候,如果使用IDE,则调用的时候就会出现一个中间的横线提醒这个方法不建议使用,如果使用记事本,会在编译的时候使用。除了在方法中可以声明为@Deprecated,在类中也可以声明:

范例3:

package haizhu.com;@Deprecatedclass Person{public String getInfo(){return "这是一个Person类";}}public class AnnotationDemo03 {public static void main(String[] args) {Person per = new Person();System.out.println(per.getInfo());}}
同样,在IDE和编译的时候都会出现警告信息,因为Person类不建议使用。


3、@SuppressWarnings

用来压制警告:

范例4:

package haizhu.com;class Demo<T>{private T var;public T getVar() {return var;}public void setVar(T var) {this.var = var;}}public class AnnotationDemo04 {@SuppressWarnings("unchecked")public static void main(String[] args) {Demo d = new Demo();d.setVar("海竹");System.out.println("内容:"+d.getVar());}}
上面是用来压制一个泛型的警告信息。可以同时压制多条警告信息,如下所示:
范例5:

package haizhu.com;@Deprecatedclass Demo<T>{private T var;public T getVar() {return var;}public void setVar(T var) {this.var = var;}}public class AnnotationDemo05 {@SuppressWarnings({"unchecked","deprecation"})public static void main(String[] args) {Demo d = new Demo();d.setVar("海竹");System.out.println("内容:"+d.getVar());}}
另外一种写法:

范例6:

package haizhu.com;@Deprecatedclass Demo<T>{private T var;public T getVar() {return var;}public void setVar(T var) {this.var = var;}}public class AnnotationDemo06 {@SuppressWarnings(value = {"unchecked","deprecation"})// 将这个内容赋给 valuepublic static void main(String[] args) {Demo d = new Demo();d.setVar("海竹");System.out.println("内容:"+d.getVar());}}

三:自定义Annotation

1、定义简单的Annotation

范例7:

package haizhu.com;public @interface MyAnnotation {// @interface 就表示这个 annotation 继承了 java.lang.annotation.Annotation 接口public String value();// 接收设置的内容}@MyAnnotation(value = "海竹")// 使用自定义的 Annotationclass Demo{}

2、向Annotation传递多个值:传递多个属性和一个属性接收多个值

也可以在Annotation中设置多个属性:

范例8:

package haizhu.com;public @interface MyAnnotation {public String key();public String value();// 接收设置的内容}@MyAnnotation(key = "haizhu",value = "海竹")// 多个属性class Demo{}
一个属性接收多个值:
范例9:

package haizhu.com;public @interface MyAnnotation {public String[] value();// 用数组接收内容}@MyAnnotation(value = {"海竹","向北西行"})// 传递一个数组class Demo{}
3、默认值

如果在一个定义好的Annotation中已经定义好了若干个属性,但是在使用Annotation时没有指定具体的内容,则在编译的时候也会出现错误,所以,在定义Annotation的时候,最好定义好默认值:

范例10:

package haizhu.com;public @interface MyAnnotation {public String value() default "海竹";// 设置默认值}@MyAnnotation// 可以不用传递class Demo{}
4、使用枚举限制设置的内容:

范例11:

package haizhu.com;public enum MyEnumName {海竹,向北西行,程序员;}
package haizhu.com;public @interface MyAnnotation {public MyEnumName value() default MyEnumName.海竹;// 使用枚举数据}@MyAnnotation(value = MyEnumName.向北西行)class Demo{}
5、@Retention 、RetentionPolicy 、@Documented 、@Inherited 、@Target
范例12:

package haizhu.com;import java.lang.annotation.Documented;import java.lang.annotation.Inherited;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.annotation.ElementType;@Documented@Inherited@Retention(value=RetentionPolicy.RUNTIME)@Target(value=ElementType.TYPE)public @interface Retention{RetentionPolicy value();}
@Retention:表示注释作用的范围,变量RetentionPolicy 有三个可选项:SOURCE、CLASS、RUNTIME

@Documented:

@Target:表示注释作用的类型,是作用在普通方法、构造方法还是作用在类上,变量ElementType 

@Inherited:用来标注一个父类的注释是否可以被子类继承,如果需要被继承,加上@Inherited 即可


四:Annotation 结合反射的应用

1、取得注释

通过反射,取得一个方法中所有的注释:

范例13:

package haizhu.com;public class ManyAnnotation{@SuppressWarnings(value = { "unchecked" })@Deprecated@Overridepublic String toString(){//在这个方法上,有三个注释return "我有很多注释。。。。";}}
package haizhu.com;import java.lang.annotation.Annotation;import java.lang.reflect.Method;public class GetAnnotationByReflect {public static void main(String[] args) throws Exception{Class<?> c = Class.forName("haizhu.com.ManyAnnotation");//取得class类实例Method m = c.getMethod("toString");//取得"toString"方法Annotation an[] = m.getAnnotations();//取得这个方法的所有注释for(Annotation a : an){System.out.println(a);//遍历,打印}}}
结果:

@java.lang.Deprecated()
为什么有三个注释,结果只取到了一个呢?因为只有一个注释默认的是“RUNTIME”类型,能够取得到,另外两个取不到。

2、取得注释的内容

范例14:

package haizhu.com;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(value=RetentionPolicy.RUNTIME)public @interface MyAnnotation {public String key() default "haizhu";public String value() default "海竹";}
package haizhu.com;public class ManyAnnotation{@SuppressWarnings(value = { "unchecked" })@Deprecated@Override@MyAnnotation(key="hello",value="world")public String toString(){return "我有很多注释。。。。";}}
package haizhu.com;import java.lang.reflect.Method;public class GetAnnotationContentByReflect {public static void main(String[] args) throws Exception{Class<?> c = Class.forName("haizhu.com.ManyAnnotation");Method m = c.getMethod("toString");if(m.isAnnotationPresent(MyAnnotation.class)){MyAnnotation ma = m.getAnnotation(MyAnnotation.class);String key = ma.key();String value = ma.value();System.out.println("key值:"+key+"\tvalue值:"+value);}}}

结果:

key值:hellovalue值:world
使用isAnnotationPresent 判断一个类是否是注释类,然后取得这个注释的key值和value值。





















原创粉丝点击