黑马程序员_Annotation

来源:互联网 发布:bs软件开发工具 编辑:程序博客网 时间:2024/05/17 01:34

------- android培训java培训 、期待与您交流! ----------

Annotation:JDK1.5之后增加的一个新特性,这种特性被称为元数据特性,在JDK1.5之后称为注释,即使用注释的方式加入一些程序的信息。

Java.lang.annotation.Annotation接口是所有的Annotation都必须实现的接口。

JDK1.5之后,系统中已经建立了如下的三个内建的Annotation类型供用户直接使用即可。

@Override:覆写的Annotation

@Deprecated:不赞成使用的Annotation

@SuppressWarnings:压制安全警告的Annotation

@Override表示方法覆写的正确性,有时在覆写方法是难免会出错,使用Override注释可以保证程序的正确执行。

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

@Deprecated,注释的Annotation本身是不建议使用的一个操作。(即被它注释的方法或类时不建议使用的)。如果调用了被他注释的方法程序不报错而是给出警告。

使用在方法上:

class Demo{@Deprecated// 声明不建议使用的操作public String getInfo(){return "这是一个Person类。" ;}};public class DeprecatedAnnotationDemo01{public static void main(String args[]){Demo d = new Demo() ;System.out.println(d.getInfo()) ;}};

使用在类上:

package Annotationprac;@Deprecatedclass Demo1{public String getInfo(){return "这是一个Person类";}}public class DeprecatedAnnotationDemo02 {public static void main(String args[]){Demo1 d = new Demo1();System.out.println(d.getInfo());}}

@SuppressWarnings:用于压制警告信息。以之前的泛型操作为例,在泛型中如果没有指定泛型类型,则使用时肯定出现安全警告。

class Demo<T>{private T var ;public T getVar(){return this.var ;}public void setVar(T var){this.var = var ;}};public class SuppressWarningsAnnotationDemo01{@SuppressWarnings("unchecked")public static void main(String args[]){Demo d = new Demo() ;d.setVar("刘丽娜") ;System.out.println("内容:" + d.getVar()) ;}};

以上只是压制了一个警告信息,当然,也可以同时压制多个警告信息,只需要以数组的形式出现即可。

@SuppressWarnings({"unchecked","deprecation"})

我们发现SuppressWarnings注释可以发现里面是使用value的字符串数组接收的,所以,在传入注释参数的时候也可以明确地指出要传给那个变量接收。

@SuppressWarnings(value={"unchecked","deprecation"})

定义简单的Annotation

Annotation定义格式:

[public] @interface Annotation名称{

       数据类型 变量名称();

}

定义一个简单的Annotation

Public @interface MyDefaultAnnotationNoneParam{}

之后就可以直接在程序中使用”@Annotation名称的格式。

@MyDefaultAnnotationNoneParam

Class Demo{} //表示在Demo类上使用Annotation.

还可以向Annotation中设置变量,使用变量接收参数;

Public @interface MyDefaultAnnotationSingleParam{

    Public String value();//接收设置的内容

}

在使用的时候必须清楚的指明变量的内容

@MyDefaultAnnotationSingleParam(“刘丽娜”)

Class Demo{}

或者也可以使用明确地标记,表示内容赋给哪个参数

@MyDefaultAnnotationSingleParam(value=“刘丽娜”)  //表示参数要赋给value属性

Class Demo{}

既然可以设置一个参数,则也就可以同时设置多个参数。

Public @interface MyDefaultAnnotationMoreParam{Public String value();//接收设置的内容Public String key();}

Annotation在使用的时候需要设置两个参数,一个是key,另外一个是value;

也可以设置一个数组进去。

Public @interface MyDefaultAnnotationArrayParam{

      Public String[] value();   //接收设置的内容

}

接收的内容本身是一个数组类型,要传递数组,类似与之前的SuppressWarnings

@interface MyDefaultAnnotationArrayParam(value={“liulina”,”刘丽娜”})

 Class Demo{}

以上所定义的全部的Annotation中有一个特点,所有的参数内容需要在使用注释的时候设置上去,那么也可以为一个参数设置默认的内容,在声明的时候使用default即可。

Public @interface MyDefaultAnnotationValue{

      Public String key() default”lln”; //指定好了默认值

      Public String value() default”liulina”; //指定好了默认值

}

使用此Annotation的时候就可以不用设置内容

@MyDefaultAnnotationValue

Class Demo{}

没有设置内容,编译也不会出现任何的错误。

在操作中,对于一个Annotation而言有时候会固定其取值范围,只能取固定的几个值,那么这个时候实际上就需要依靠枚举。

Public enum MyName{      //定义枚举类型

      Lln,liulina,Linda;

}

以后的Annotation的取值,只能从这三个值中取走。

Public @interface MyDefaultAnnotationEnum{

      Public MyName name() default MyName.Lln;  //指定默认值

}

以上的Annotation已经设置好了一个枚举中的内容作为默认值,那么外部使用此Annotation的时候也需要从枚举固定取值。

@MyDefaultAnnotationEnum(name=MyName.linda)   //只能从固定的枚举中取内容

Class Demo{}

Annotation中,可以使用Retention定义一个Annotation的保存范围,此Annotation的定义如下:

Public @interface Retention{

      RetentionPolicy value();

}

在以上的Rentetion定义中存在了一个RententionPolicy的变量,此变量用于指定Annotation的保存范围,RetentionPolicy包含三种范围;

SOURCE:此Annotation类型的信息只会保留在程序源文件之中(*.java),编译之后不会保存在编译好的类文件(*.class)之中

CLASS:此Annotation类型将保留在程序源文件(*.java)和编译之后的类文件(*.class)之中,在使用此类的时候,这些Annotation信息将不会被加载到虚拟机(JVM)之中,如果一个Annotation声明时没有指定范围,则默认是此范围

RUNTIME:此Annotation类型的信息保留在源文件(*.java)、类文件(*.class)在执行时也会加载到JVM之中。

import java.lang.annotation.Retention ;import java.lang.annotation.RetentionPolicy ;@Retention(value=RetentionPolicy.RUNTIME)// 表示此Annotation在运行时有效public @interface MyDefaultRententionAnnotation{public String name() default "刘丽娜" ;}

如果想要一个Annotation起作用,则必须结合反射机制获取Annotation的内容。

public class SimpleBeanOne{@SuppressWarnings("unchecked") @Deprecated@Overridepublic String toString(){return "Hello LiuLina!!!" ;}};


同时设置了三个Annotation,那么此时注意,只有Depreacted的Annotation的定义范围是RUNTIME范围,所以此时通过反射的话只能取得一个。

import java.lang.annotation.Annotation ;import java.lang.reflect.Method ;public class ReflectDemo01{public static void main(String args[]) throws Exception{// 所有异常抛出Class <?> c = null ;c = Class.forName("org.lxh.demo16.reflectannotation.SimpleBeanOne") ;Method toM = c.getMethod("toString") ;// 找到toString()方法Annotation an[] = toM.getAnnotations() ;// 取得全部的Annotationfor(Annotation a:an){// 使用 foreach输出System.out.println(a) ;}}};

此时,已经取得了一个Annotation(@Depreacted).

以上的操作代码实际上是通过三个系统内建的Annotation完成的,那么也可以自定义一个Annotation

import java.lang.annotation.Retention ;import java.lang.annotation.RetentionPolicy ;@Retention(value=RetentionPolicy.RUNTIME)// 此Annotation在类执行时依然有效public @interface MyDefaultAnnotationReflect{public String key() default "LLN" ;public String value() default "刘丽娜" ;}

以上的Annotation范围是在运行时依然有效,下面定义一个类使用此Annotation

public class SimpleBeanTwo{@SuppressWarnings("unchecked") @Deprecated@Override@MyDefaultAnnotationReflect(key="MLDN",value="www.mldnjava.cn")public String toString(){return "Hello LiuLina!!!" ;}};

下面使用反射取得指定的Annotation,因为现在唯一设置内容的就是MyDefaultRelfect

import org.lxh.demo16.reflectannotation.MyDefaultAnnotationReflect ;import java.lang.annotation.Annotation ;import java.lang.reflect.Method ;public class ReflectDemo02{public static void main(String args[]) throws Exception{// 所有异常抛出Class <?> c = null ;c = Class.forName("org.lxh.demo16.reflectannotation.SimpleBeanTwo") ;Method toM = c.getMethod("toString") ;// 找到toString()方法if(toM.isAnnotationPresent(MyDefaultAnnotationReflect.class)){// 判断是否是指定的AnnotationMyDefaultAnnotationReflect mda = null ;mda = toM.getAnnotation(MyDefaultAnnotationReflect.class) ;// 得到指定的AnnotationString key = mda.key() ;// 取出设置的keyString value = mda.value() ;// 取出设置的valueSystem.out.println("key = " + key) ;System.out.println("value = " + value) ;}}};

之前定义的Annotation,如果没有明确地说明可以在任意的位置上使用。

如果现在需要指定其使用范围的话,则必须使用@Target注释。

import java.lang.annotation.Target ;import java.lang.annotation.ElementType ;import java.lang.annotation.Retention ;import java.lang.annotation.RetentionPolicy ;@Target(ElementType.TYPE)// 此注释只能用在类上@Retention(value=RetentionPolicy.RUNTIME)public @interface MyTargetAnntation{public String key() default "LLN" ;public String value() default "刘丽娜" ;}


此时在SimpleBean的类及方法的声明上使用此Annotation

@MyTargetAnntation(key="heima ",value="heimapeixun ")public class SimpleBean{@MyTargetAnntation(key="heima",value="heimapeixun ")public String toString(){return "Hello LiuLina!!!" ;}};

如果现在希望一个Annotation可以在类及方法上同时使用的话,则必须设置多个范围。

@Target({ElementType.TYPE,ElementType.METHOD})

@Documented,可以用在任何的Annotation上使用,所有的Annotation默认情况下都是使用@Documented进行注释的,而且在生成javadoc的时候可以通过@Documented设置一些说明信息。

import java.lang.annotation.Documented ;@Documentedpublic @interface MyDocumentedAnntation{public String key() default "LLN" ;public String value() default "LiuLina" ;}

成功之后,在使用此Annotation的时候就可以增加一些信息上去了。

@MyDocumentedAnntation(key="heima ",value="heimapeixun ")public class SimpleBeanDocumented{/** * 此方法在对象输出时调用,返回对象信息 */@MyDocumentedAnntation(key="heima ",value="heimapeixun ")public String toString(){return "Hello LiuLina!!!" ;}};

之后通过javadoc命令,生成javadoc文档。(javadoc –d doc SimpleBeanDocumented.java)

@Inherited 注释,此注释表示一个Annotation是否可以被继承下来

import java.lang.annotation.Retention ;import java.lang.annotation.RetentionPolicy ;import java.lang.annotation.Documented ;import java.lang.annotation.Inherited ;@Documented@Inherited@Retention(value=RetentionPolicy.RUNTIME)public @interface MyInheritedAnnotation{public String name() ;}

定义一个父类,在父类上使用此Annotation

@MyInheritedAnnotation(name="刘丽娜 ")public class Person{};

定义子类

public class Student extends Person{};

按照所解释的,使用Inherited声明的Annotation是可以被子类继承下来的。

import java.lang.annotation.Annotation ;import org.lxh.demo16.inheriteddemo.MyInheritedAnnotation ;public class ReflectInheritedDemo{public static void main(String args[]) throws Exception{Class<?> c = null ;c = Class.forName("org.lxh.demo16.inheriteddemo.Student") ;Annotation ann[] = c.getAnnotations() ;// 取得全部的Annotationfor(Annotation a:ann){// 输出System.out.println(a) ;}// 继续取得此Annotation设置的内容if(c.isAnnotationPresent(MyInheritedAnnotation.class)){MyInheritedAnnotation mda = null ;mda = c.getAnnotation(MyInheritedAnnotation.class) ;String name = mda.name() ;// 取出name的内容System.out.println("name = " + name) ;}}


 












 

原创粉丝点击