Java注解

来源:互联网 发布:cmd 80端口 编辑:程序博客网 时间:2024/05/22 08:25

一、什么是JAVA的注解?

     注解,顾名思义就是对某种事物添加一个注释说明的意思,标注某种事物的特征以及形态,供日后其它人遇到该事物时有一个直观的认识。JAVA注解又叫JAVA标注,JAVA语言提供一套机制,可以在包、类(包括接口、枚举、注解)、方法、字段(包括常量)、方法参数、局部变量、构造器和注解这些元素上添加标注(即为这些元素附上一些标识信息),在某些业务需要的情况下,可以通过JAVA的反射机制获得这些元素的标识信息,做进一步的操作。

 

二、自定义JAVA注解

1、为什么要自定义注解?

在JDK5.0以后默认提供了三个常用的注解类:
1)、@Override:只能作用于方法之上,用来告诉别人这个方法是改写父类的一个方法。
2)、@Deprecated:可以作用于程序中任何元素之上,用 @Deprecated 注释的程序元素,不鼓励程序员使用,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
3)、@SuppressWarnings:只能作用于TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE上,用于关闭编译器提示的警告信息。
因为在日常工作中,三个注解类是完全不能满足业务需求的,所以要根据自己的业务需求,定义自己的注解类。


2、如何自定义注解?

自定义注解的步聚:
1)、通过@interface关键字声明注解名称,和定义类(class)、接口(interface)、枚举(emum)的方式一样,只有关键词不一样,用“@interface”标识。
2)、使用JAVA内置的四个元注解对自定义的注解作用范围做一些限制。

3、什么是元注解?

元注解,就是专门用来定义注解的注解,主要作用就是用于约束自定义注解的功能。比如注解只能用在方法上、类上或字段上。其中JDK5.0中内置的三个注解,也是通过元注解来约束的。

元注解有哪些呢?
[java] view plaincopyprint?
  1. /* 
  2.  * JDK自带的元注解有:@Target,@Retentio,@Documente,@Inherited 
  3.  *  
  4.  * @Target:指示该注解类型用于什么元素之上,如果注解没有添加@Target标示,则可以作用于任一程序元素上,如果加上了@Target注解类型约束,则编译器会强制检查作用于程序元素上的限制。 
  5.  * 可选的ElementType注解类型包括: 
  6.  * ElementType.ANNOTATION_TYPE:只能作用于注解类型上 
  7.  * ElementType.CONSTRUCTOR:只能作用于构造方法上 
  8.  * ElementType.FIELD:只能作用于字段上(包括枚举常量) 
  9.  * ElementType.LOCAL_VARIABLE:只能作用于局部变量上 
  10.  * ElementType.METHOD:只能作用于方法上 
  11.  * ElementType.PACKAGE:只能作用于包上 
  12.  * ElementType.PARAMETER:只能作用于方法参数声明上 
  13.  * ElementType.TYPE:只能作于类、接口、枚举、注解上 
  14.  *  
  15.  * @Retention:指示在什么级别保留注解信息。如果注释类型声明中不存在Retention,则保留策略默认为 RetentionPolicy.CLASS。  
  16.  * 可选的RetentionPolicy保留级别包括:  
  17.  * RetentionPolicy.SOURCE:仅保留在源代码中,javac编译完后,会丢弃注解。不会保存在编译好的class文件上。 
  18.  * RetentionPolicy.CLASS:保留在源代码和class文件中,jvm加载class字节码文件时,不会加载注解。 
  19.  * RetentionPolicy.RUNTIME:即保留在源代码和class文件中,也会被jvm加载到内存当中,所以可通过反射的方式读取注解信息。 
  20.  *  
  21.  * @Documented:标示了此注解的元素,注释将成为注解元素公共API的一部分。 
  22.  *  
  23.  * @Inherited:指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。 
  24.  */  

4、自定义注解及使用示例

1)、自定义一个类级别的注解TypeAnnotation

[java] view plaincopyprint?
  1. package annotation;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Retention;  
  6. import java.lang.annotation.RetentionPolicy;  
  7. import java.lang.annotation.Target;  
  8.   
  9. @Retention(RetentionPolicy.RUNTIME) //此注解会一直保留到运行时  
  10. @Target(ElementType.TYPE)           //此注解应用于类、接口、枚举、注解上  
  11. @Documented //此注解会包含在javadoc中  
  12. public @interface TypeAnnotation {  
  13.   
  14.     String value();  
  15.       
  16. }  

2)、自定义一个方法级别的注解MethodAnnotation

[java] view plaincopyprint?
  1. package annotation;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Retention;  
  6. import java.lang.annotation.RetentionPolicy;  
  7. import java.lang.annotation.Target;  
  8.   
  9. @Retention(RetentionPolicy.RUNTIME)  
  10. @Target(ElementType.METHOD)  
  11. @Documented  
  12. public @interface MethodAnnotation {  
  13.   
  14.     String name();  
  15.       
  16.     String address();  
  17.       
  18. }  

3)、定义一个注解使用类TestAnnotation,并使用这两个注解

[java] view plaincopyprint?
  1. package annotation;  
  2.   
  3. @TypeAnnotation("hi,i am TypeAnnotation...")  
  4. public class AnnotationResource {  
  5.   
  6.     @MethodAnnotation(name="zhangsan",address="北京")  
  7.     public void getPersonInfo() {  
  8.         System.out.println("hello,i am zhangsan");  
  9.     }  
  10.       
  11.     @MethodAnnotation(name="lisi",address="上海")  
  12.     public String getPersonInfo2() {  
  13.         return "lisi,来自上海!";  
  14.     }  
  15.       
  16. }  

4)、然后使用反射的方式获取这两个注解的信息

[java] view plaincopyprint?
  1. package annotation;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. /** 
  6.  * 测试注解的使用 
  7.  */  
  8. public class TestAnnotation {  
  9.   
  10.     public static void main(String[] args) {  
  11.         AnnotationResource ar = new AnnotationResource();  
  12.         Class clazz = ar.getClass();  
  13.         //通过反射获得类注解信息   
  14.         if (clazz.isAnnotationPresent(TypeAnnotation.class)) {  
  15.             TypeAnnotation typeAnnotation = (TypeAnnotation) clazz.getAnnotation(TypeAnnotation.class);  
  16.             System.out.println(typeAnnotation.value());  
  17.         }  
  18.           
  19.         //通过反射获得方法注解信息   
  20.         Method[] methods = clazz.getMethods();  
  21.         for (Method method : methods) {  
  22.             if (method.isAnnotationPresent(MethodAnnotation.class)) {  
  23.                 MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);  
  24.                 System.out.print("姓名:" + methodAnnotation.name() + "\t");  
  25.                 System.out.println("地址:" + methodAnnotation.address() + "\t");  
  26.             }  
  27.         }  
  28.     }  
  29. }  

注意:
1、自定义的Annotation,隐式的继续自java.lang.Annotation,所以不能在继承其它的类或接口。
2、在Annotation中声明的方法只能是public的,或者默认不加访问修饰符。
3、方法的返回值类型只限8种基本类型byteint、short、longfloat、double、char、boolean,和String、enum、annotation、Class,以及这些类型的数组。
4、方法不能有参数
5、方法不能抛异常
转自:http://blog.csdn.net/xyang81/article/details/7250822
原创粉丝点击