首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java 诠注 Anonotation

2012-08-26 
Java 注解 Anonotation1、什么是注解Annotation表示一种注释的语法,在Java中最早提倡的是程序与配置相分离,

Java 注解 Anonotation
1、什么是注解

Annotation表示一种注释的语法,在Java中最早提倡的是程序与配置相分离,而最新的理论是把所有配置直接写入到代码中,如果想完成这样的功能,则使用Annotation。

?

2、系统内建的Annotation

?

2.1??@Override

重写父类的方法

?

2.2??@Deprecated

表示不建议使用的操作,如果使用该操作也不报错,只是在编辑器中出现横线警告信息,不建议使用。如Date对像中的很多方法。

@Deprecated

public?int?getDay()?{

????return?normalize().getDayOfWeek()?-?gcal.SUNDAY;

}

?

2.3??@SuppressWaring表示压制警告,如果出现警告信息,则可以压制不提示。@SuppressWaring的属性String[]?value()为数组,说明可以同时压制多个警告。

@Target({TYPE,?FIELD,?METHOD,?PARAMETER,?CONSTRUCTOR,?LOCAL_VARIABLE})

@Retention(RetentionPolicy.SOURCE)

public?@interface?SuppressWarnings?{

????String[]?value();

}

?

3、自定义Annotation

?

3.1?语法

public?@interface?名称{

}


3.2?定义MyAnnotaion

package?com.chenzehe.annotation;

??? public?@interface?MyAnnotation?{

}

如果要使用此Annotation,则使用@符访问,不在同一个包中需要导入。如下面Info类的使用:

package?com.chenzehe.annotation;

@MyAnnotation

public?class?Info?{

}


3.3?Annotation的属性定义

Annotation的属性定义以()结尾。

package?com.chenzehe.annotation;

public?@interface?MyAnnotation?{

????public?String?key();

????public?String?value();

}

上面Annotation定义了两个变量key和value,如果要使用此Annotation,则必须明确的给出其内容。如:

package?com.chenzehe.annotation;

@MyAnnotation(key="name",value="chenzehe")

public?class?Info?{

}

?

如果想给Annotation的变量设置默认值,则使用default关键字完成,如:

package?com.chenzehe.annotation;

public?@interface?MyAnnotation?{

? public?String?key()?default?"name";

??? public?String?value()?default?"chenzehe";

}

使用此Annotation时,可以不用显示的设置变量值,而使用默认值。


3.4?Annotation中的属性值可以通过枚举限制

定义枚举类型Color:

package?com.chenzehe.annotation;

public?enum?Color?{

????RED,GLREN,BLUE;

}

在MyAnnotation中定义一个Color类型的变量:

package?com.chenzehe.annotation;

public?@interface?MyAnnotation?{

????public?Color?color()?default?Color.RED;

}

则使用MyAnnotation中的color变量时,值只能取Color中定义的类型:

package?com.chenzehe.annotation;

@MyAnnotation(color="red")

public?class?Info?{

}

上面给变量color赋值出错,正确如下:

package?com.chenzehe.annotation;

@MyAnnotation(color?=?Color.RED)

public?class?Info?{

}


3.5?Annotation中的属性为数组类型

如果Annotation中的属性为数组类型,则使用的时候必须按照数组的方式操作。

package?com.chenzehe.annotation;

public?@interface?MyAnnotation?{

public?String[]?urls();

}

使用:

package?com.chenzehe.annotation;

@MyAnnotation(urls?=?{?"www.baidu.com",?"g.cn"?})

public?class?Info?{

}

4、注释类型?Retention和枚举?RetentionPolicy

@Documented

@Retention(value=RUNTIME)

@Target(value=ANNOTATION_TYPE)

public?@interface?Retention

????? 指示注解类型的注释要保留多久,也就是作用范围。如果注释类型声明中不存在?Retention?注释,则保留策略默认为?RetentionPolicy.CLASS。只有元注释类型直接用于注释时,Target?元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。

枚举?RetentionPolicy定义了三种Annotation的范围:

CLASS?在编译之后的class文件中作用

RUNTIME?在运行的时候起作用

SOURCE?只在源代码中起作用

系统内置的三个Annotation的作用域分别为:

@Override:@Retention(value=SOURCE)源码

@Deprecated:@Retention(value=RUNTIME)运行时

@SuppressWarnings:@Retention(value=SOURCE)源码

?

5、反射与Annotation

一个Annotation如果要想起作用,则肯定要依赖反射机制,通过反射可以取得一个方法上声明的?Annotation全部内容。任何一下自定义的Annotation都是继承了java.lang.annotation.Annotation接口。

在Field?Method?Constructor?的父类AccessibleObject??定义了如下与Annotation操作相关的方法:

取得全部Annotation?:public?Annotation[]?getAnnotations()??

判断操作的是否是指定的Annotation:public?boolean?isAnnotationPresent(Class<??extends?Annotation>?annotationClass)?

例:下面Info类中toString()方法使用的Annotation,在Test类中用反射访问这些Annotation

package?com.chenzehe.annotation;

public?class?Info?{

????@Override

????@Deprecated

????@SuppressWarnings(value?=?"")

????public?String?toString()?{

????????return?"Hello?World!";

????}

}

?

package?com.chenzehe.annotation;

import?java.lang.annotation.Annotation;

import?java.lang.reflect.Method;

public?class?Test?{

????public?static?void?main(String[]?args)?throws?Exception?{

????????Class<?>?cls?=?Class.forName("com.chenzehe.annotation.Info");

????????Method?method?=?cls.getMethod("toString");

????????Annotation[]?annotations?=?method.getAnnotations();

????????for?(int?i?=?0;?i?<?annotations.length;?i++)?{

????????????System.out.println(annotations[i]);

????????}

????}

}

输出:@java.lang.Deprecated(),而Info类中使用的三个Annotation中,只有Deprecated的范围为runtime,说明只有范围在runtime的才能被找到。

?

把MyAnnotation类改成runtime范围,并在Test类中用反射取得他的属性:

package?com.chenzehe.annotation;

import?java.lang.annotation.Retention;

import?java.lang.annotation.RetentionPolicy;

@Retention(value?=?RetentionPolicy.RUNTIME)

public?@interface?MyAnnotation?{

????public?String?key()?default?"name";

????public?String?value();

}

在Info中使用该Annotation:

package?com.chenzehe.annotation;

public?class?Info?{

????@Override

????@Deprecated

????@SuppressWarnings(value?=?"")

????@MyAnnotation(value="chenzehe")

????public?String?toString()?{

????????return?"Hello?World!";

????}

}

在Test类中使用反射取得其属性:

package?com.chenzehe.annotation;

import?java.lang.annotation.Annotation;

import?java.lang.reflect.Method;

public?class?Test?{

???? public?static?void?main(String[]?args)?throws?Exception?{

???????? Class<?>?cls?=?Class.forName("com.chenzehe.annotation.Info");

???????? Method?method?=?cls.getMethod("toString");

???????? Annotation[]?annotations?=?method.getAnnotations();

???????? for?(int?i?=?0;?i?<?annotations.length;?i++)?{

???????????? if?(method.isAnnotationPresent(MyAnnotation.class))?{

???????????????? MyAnnotation?myAnnotation?=?method.getAnnotation(MyAnnotation.class);

???????????????? String?key?=?myAnnotation.key();

???????????????? String?value?=?myAnnotation.value();

???????????????? System.out.println(key?+?":"?+?value);

???????????? }

???????? }

????}

}

?

6、Target

在java.lang.annotation中已定义的注解类型Target?,用于指定所定义的注解使用的范围为方法、类、属性等。

默认情况下一个自定义的Annotation可以在任意地方使用,如自定义的MyAnnotation,如果没有指定Target,则可以在任意地方使用:

package?com.chenzehe.annotation;

@MyAnnotation()

public?class?Info?{

????@MyAnnotation()

????private?Stringname;

????@MyAnnotation()

????public?String?toString()?{

????????return?"Hello?World!";

????}

}

在Target的定义中,value的属性类型为?ElementType[],所指定的范围有以下八种:

1、只能在Annotation中出现:ANNOTATION_TYPE?

2、只能在构造方法中出现:CONSTRUCTOR?

3、在属性中出现:FIELD?

4、只能在本地变量中出现:LOCAL_VARIABLE?

5、在方法上出现:METHOD?

6、在包声明中出现:PACKAGE?

7、在参数声明中出现:PARAMETER?

8、类、接口(包括注释类型)或枚举声明中使用:?TYPE?

如以下自定义的MyAnnotation只能在方法中使用:

package?com.chenzehe.annotation;

import?java.lang.annotation.ElementType;

import?java.lang.annotation.Retention;

import?java.lang.annotation.RetentionPolicy;

import?java.lang.annotation.Target;

@Retention(value?=?RetentionPolicy.RUNTIME)

@Target(value=(ElementType.METHOD))

public?@interface?MyAnnotation?{

??? public?String?key()?default?"name";

??? public?String?value()?default?"chenzehe";

}

Target中的属性value定义为数组类型,所以可以同时设置多个ElementType,如:

@Target(value?=?{?ElementType.METHOD,?ElementType.FIELD?})

?

7、Document注解

在java.lang.annotation中定义的注解类型Documented?,指示某一类型的注释将通过?javadoc?和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用?Documented?来注释的,则其注释将成为注释元素的公共?API?的一部分。?

如声明MyAnnotation注解:

package?com.chenzehe.annotation;

import?java.lang.annotation.Documented;

import?java.lang.annotation.ElementType;

import?java.lang.annotation.Retention;

import?java.lang.annotation.RetentionPolicy;

import?java.lang.annotation.Target;

@Documented

@Retention(value?=?RetentionPolicy.RUNTIME)

@Target(value?=?{?ElementType.METHOD,?ElementType.FIELD?})

public?@interface?MyAnnotation?{

????public?String?key()?default?"name";

????public?String?value()?default?"chenzehe";

}

在Info类中使用:

package?com.chenzehe.annotation;

public?class?Info?{

????/**

? ?? *?此方法是覆盖Object中的toString()方法

? ?? */

????@MyAnnotation()

????public?String?toString()?{

????????return?"Hello?World!";

????}

}

可以通过eclipse的export导出javadoc,在其注释中能看到上面编写的注释

?

8、Inherited

在java.lang.annotation中声明Inherited?,表示该annotation是否被该子类断承下去,如果没有此注解,说明不能被断承。

如自定义的MyAnnotation,加入@Inherited,说明此Annotation可以被子类断承:

package?com.chenzehe.annotation;

import?java.lang.annotation.Inherited;

import?java.lang.annotation.Retention;

import?java.lang.annotation.RetentionPolicy;

@Inherited

@Retention(value?=?RetentionPolicy.RUNTIME)

public?@interface?MyAnnotation?{

???public?String?key()?default?"name";

????public?String?value()?default?"chenzehe";

}

在Info类中使用该Annotation:

package?com.chenzehe.annotation;

@MyAnnotation

public?class?Info?{

}

创建Info类的子类PersonInfo:

package?com.chenzehe.annotation;

public?class?PersonInfo?extends?Info?{

}

使用反射取得PersonInfo类的annotation信息:

package?com.chenzehe.annotation;

import?java.lang.annotation.Annotation;

public?class?Test?{

????public?static?void?main(String[]?args)?throws?Exception?{

????????Class<?>?cls?=?Class.forName("com.chenzehe.annotation.PersonInfo");

????????Annotation[]?annotations?=?cls.getAnnotations();

????????for?(int?i?=?0;?i?<?annotations.length;?i++)?{

????????????System.out.println(annotations[i]);

????????}

????}

}

如果MyAnnotation中加入@Inherited,则可以取到MyAnnotaion信息,如果没有加则取不到。

?

热点排行