java注解详解.doc_第1页
java注解详解.doc_第2页
java注解详解.doc_第3页
java注解详解.doc_第4页
java注解详解.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JAVA 注解的几大作用及使用方法详解注解(Annotation)1、Annotation的工作原理:JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。Annotation可以从源文件、class文件或者在运行时通过反射机制多种方式被读取。常见的作用有以下几种:1,生成文档。这是最常见的,也是java 最早提供的注解。常用的有see param return 等2,跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。3,在编译时进行格式检查。如override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。*interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。*方法的名称就是参数的名称,返回值类型就是参数的类型。*可以通过default来声明参数的默认值。父类,接口Java.lang.annotation包 java.lang.annotation 中包含所有已定义或自定义注解所需用到的原注解和接口。如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。该包同时定义了四个元注解;常见注解Override注解:注释类型 OverrideTarget(value=METHOD)Retention(value=SOURCE)public interface OverrideOverride注解表示子类要重写父类的对应方法。下面是一个使用Override注解的例子:class A private String id; A(String id) this.id = id; Override public String toString() return id; Deprecated注解:注释类型 DeprecatedDocumentedRetention(value=RUNTIME)public interface DeprecatedDeprecated注解表示方法是不被建议使用的。下面是一个使用Deprecated注解的例子:class A private String id; A(String id) this.id = id; Deprecated public void execute() System.out.println(id); public static void main(String args) A a = new A(a123); a.execute(); SuppressWarnings注解:注释类型 SuppressWarningsTarget(value=TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE)Retention(value=SOURCE)public interface SuppressWarnings指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。下面是一个使用SuppressWarnings注解的例子:SuppressWarnings(unchecked)public static void main(String args) List list = new ArrayList(); list.add(abc);自定义注解使用interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。1,自定义最简单的注解:public interface MyAnnotation 使用自定义注解:public class AnnotationTest2 MyAnnotation public void execute() System.out.println(method); 2,添加变量:public interface MyAnnotation String value1();使用自定义注解:public class AnnotationTest2 MyAnnotation(value1=abc) public void execute() System.out.println(method); 添加默认值:public interface MyAnnotation String value1() default abc;3、多变量使用枚举:public interface MyAnnotation String value1() default abc; MyEnum value2() default MyEnum.Sunny;enum MyEnum Sunny,Rainy使用自定义注解:public class AnnotationTest2 MyAnnotation(value1=a, value2=MyEnum.Sunny) public void execute() System.out.println(method); 4、数组变量:public interface MyAnnotation String value1() default abc;使用自定义注解:public class AnnotationTest2 MyAnnotation(value1=a,b) public void execute() System.out.println(method); 当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。5、限定注解的使用:限定注解使用Target。DocumentedRetention(value=RUNTIME)Target(value=ANNOTATION_TYPE)public interface Target指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:Target(ElementType.ANNOTATION_TYPE) public interface MetaAnnotationType . 此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:Target() public interface MemberType . 这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:Target(ElementType.FIELD, ElementType.METHOD, ElementType.FIELD) public interface Bogus . public enum ElementTypeextends Enum程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。ANNOTATION_TYPE注释类型声明CONSTRUCTOR构造方法声明FIELD字段声明(包括枚举常量)LOCAL_VARIABLE局部变量声明METHOD方法声明PACKAGE包声明PARAMETER参数声明TYPE类、接口(包括注释类型)或枚举声明注解的使用限定的例子:Target(ElementType.METHOD)public interface MyAnnotation String value1() default abc;元注解元注解是指注解的注解。包括 Retention Target Document Inherited四种。Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括: Target(ElementType.TYPE) /接口、类、枚举、注解Target(ElementType.FIELD) /字段、枚举的常量Target(ElementType.METHOD) /方法Target(ElementType.PARAMETER) /方法参数Target(ElementType.CONSTRUCTOR) /构造函数Target(ElementType.LOCAL_VARIABLE)/局部变量Target(ElementType.ANNOTATION_TYPE)/注解 Target(ElementType.PACKAGE) /包 packag注解必须在package-info.java 中声明Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括: Retention(RetentionPolicy.SOURCE) /注解仅存在于源码中,在class字节码文件中不包含 Retention(RetentionPolicy.CLASS) / 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得, Retention(RetentionPolicy.RUNTIME) / 注解会在class字节码文件中存在,在运行时可以通过反射获取到Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与see,param 等。 Inherited 允许子类继承父类中的注解TargetTarget用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。 例:Target(TYPE,METHOD,FIELD,CONSTRUCTOR)public interface TestA /这里定义了一个空的注解。 这个类专门用来测试注解使用TestA /使用了类注解public class UserAnnotation TestA /使用了类成员注解 private Integer age; TestA /使用了构造方法注解 public UserAnnotation() TestA /使用了类方法注解 public void a() TestA /使用了局部变量注解 Map m = new HashMap(0); TestA /使用了方法参数注解 public void b(TestA Integer a) RetentionRetention用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种,分别表示注解保存在类文件、JVM运行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。无属性注解Retention 参数 RetentionPolicy。这个注解还没有特殊的属性值。 简单演示下如何使用: import java.lang.annotation.ElementType;import java.lang.annotation.Target;/* * 定义注解 Test * 首先使用ElementType.TYPE(需要在package-info.java中声明)* 运行级别定为 运行时,以便后面测试解析 */ Target(ElementType.TYPE)Retention(RetentionPolicy.RUNTIME)public interface TestA 有属性注解interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。代码:/* * 定义注解 Test * 为方便测试:注解目标为类 方法,属性及构造方法 * 注解中含有三个元素 id ,name和 gid; * id 元素 有默认值 0*/ Target(TYPE,METHOD,FIELD,CONSTRUCTOR)Retention(RetentionPolicy.RUNTIME)public interface TestA String name();int id() default 0;Class gid();测试类import java.util.HashMap;import java.util.Map; /* 这个类专门用来测试注解使用*/ TestA(name=type,gid=Long.class) /类成员注解public class UserAnnotation TestA(name=param,id=1,gid=Long.class) /类成员注解private Integer age;TestA (name=construct,id=2,gid=Long.class)/构造方法注解public UserAnnotation()TestA(name=public method,id=3,gid=Long.class) /类方法注解public void a()Map m = new HashMap(0);TestA(name=protected method,id=4,gid=Long.class) /类方法注解protected void b()Map m = new HashMap(0);TestA(name=private method,id=5,gid=Long.class) /类方法注解private void c()Map m = new HashMap(0);public void b(Integer a) 读取定义注解内容import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Method; public class ParseAnnotation /*A 简单打印出UserAnnotation 类中所使用到的类注解* 该方法只打印了 Type 类型的注解* throws ClassNotFoundException*/public static void parseTypeAnnotation() throws ClassNotFoundException Class clazz = Class.forName(com.tmser.annotation.UserAnnotation); Annotation annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) TestA testA = (TestA)annotation;System.out.println(id= +testA.id()+; name= +testA.name()+; gid = +testA.gid(); /结果为id=0;name=type;gid =classjava.lang.Long/* B简单打印出UserAnnotation 类中所使用到的方法注解* 该方法只打印了 Method 类型的注解* throws ClassNotFoundException*/public static void parseMethodAnnotation()Method methods = UserAnnotation.class.getDeclaredMethods(); for (Method method : methods) / 判断方法中是否有指定注解类型的注解 boolean hasAnnotation = method.isAnnotationPresent(TestA.class); if (hasAnnotation) /根据注解类型返回方法的指定类型注解 TestA annotation = method.getAnnotation(TestA.class); System.out.println(method = + method.getName() + ; id = + annotation.id() + ; description = + () + ; gid= +annotation.gid(); method = c ; id = 5 ; description = private method; gid= class java.lang.Longmethod = a ; id = 3 ; description = public method; gid= class java.lang.Longmethod = b ; id = 4 ; description = protected method; gid= class java.lang.Long/* C简单打印出UserAnnotation 类中所使用到的构造方法注解* 该方法只打印了 Method 类型的注解* throws ClassNotFoundException*/public static void parseConstructAnnotation()Constructor constructors = UserAnnotation.class.getConstructors(); for (Constructor constructor : constructors) /判断构造方法中是否有指定注解类型的注解 boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class); if (hasAnnotation) /根据注解类型返回方法的指定类型注解 TestA annotation =(TestA) constructor.getAnnotation(TestA.class); System.out.println(constructor = + constructor.getName() + ; id = + annotation.id() + ; description = + () + ; gid= +annotation.gid(); constructor=com.tmser.annotation.UserAnnotation;id=2;description =construct;gid=classjava.lang.Longpublic static void main(String args) throws ClassNotFoundException parseTypeAnnotation();parseMethodAnnotation();parseConstructAnnotation();/field是一样的,省略之Documented 在帮助文档中加入注解:要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。在自定义注解中声明构建注解文档:Documentedpublic interface MyAnnotation String value1() default abc;使用自定义注解:public class AnnotationTest2 MyAnnotation(value1=a,b) public void execute() System.out.println(method); Inherited 在注解中使用继承:默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。DocumentedRetention(value=RUNTIME)Target(value=ANNOTATION_TYPE)public interface Inherited指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。自定义注解案例实例1:下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:自定义注解:Retention(RetentionPolicy.RUNTIME)public interface MyAnnotation String value1() default abc;使用自定义注解:public class AnnotationTest2 MyAnnotation(value1=a,b) Deprecated public void execute() System.out.println(method); 读取注解中的信息:public static void main(String args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException AnnotationTest2 annotationTest2 = new AnnotationTest2(); /获取AnnotationTest2的Class实例 Class c = AnnotationTest2.class; /获取需要处理的方法Method实例 Method method = c.getMethod(execute, new Class); /判断该方法是否包含MyAnnotation注解 if(method.isAnnotationPresent(MyAnnotation.class) /获取该方法的MyAnnotation注解实例 MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class); /执行该方法 method.invoke(annotationTest2, new Object); /获取myAnnotation String value1 = myAnnotation.value1(); System.out.println(value10); /获取方法上的所有注解 Annotation annotations = method.getAnnotations(); for(Annotation annotation : annotations) System.out.println(annotation); 实例2:DocumentedTarget(ElementType.TYPE,ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)public interface Yts public enum YtsTypeutil,entity,service,model; public YtsType classType() default YtsType.util;Documented Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) Inherited public interface HelloWorld public String name()default ; public class ParseAnnotation public void parseMethod(Class clazz) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException,SecurityException, NoSuchMethodException, InstantiationException Object obj = clazz.getConstructor(new Class).newInstance(new Object); for(Method method : clazz.getDeclaredMethods() HelloWorld say = method.getAnnotation(HelloWorld.class); String name = ; if(say != nul

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论