分享

张龙 Annotation学习笔记

 狼志凌云 2011-10-08

首先明确一个概念:
annotation=注解      comment=注释  不要混淆了

a) Override注解表示子类要重写(override)父类的对应方法。
举例:OverrideTest.java

 

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. public class OverrideTest   
  4. {   
  5.     @Override  
  6.         //该注解表示该类重写了父类的方法   
  7.     public String toString()   
  8.     {   
  9.         return "This is OverrideTest";   
  10.     }   
  11.        
  12.     public static void main(String[] args)   
  13.     {   
  14.         OverrideTest test = new OverrideTest();   
  15.            
  16.         System.out.println(test);   
  17.     }   
  18. }   

b) Deprecated注解表示方法是不建议被使用的。
举例:DeprecatedTest.java 

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. public class DeprecatedTest   
  4. {   
  5.     @Deprecated  
  6.         //该注解表示这个方法是废弃的,不建议被使用的   
  7.     public void doSomething()   
  8.     {   
  9.         System.out.println("do something!");   
  10.     }   
  11.        
  12.     public static void main(String[] args)   
  13.     {   
  14.         DeprecatedTest test = new DeprecatedTest();   
  15.            
  16.         test.doSomething();   
  17.            
  18.            
  19.            
  20.            
  21.            
  22.            
  23. //      Date date = new Date();   
  24. //         
  25. //      System.out.println(date.toLocaleString());   
  26.     }   
  27. }  

c) SuppressWarnings注解表示抑制警告。
举例:SuppressWarningsTest.java

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. import java.util.Date;   
  4. import java.util.Map;   
  5. import java.util.TreeMap;   
  6.   
  7. public class SuppressWarningsTest   
  8. {   
  9.     @SuppressWarnings({"unchecked""deprecation"})   
  10.    //该注解表示一些警告会被压制住   
  11.    //unchecked表示不对集合没有使用泛型进行警告   
  12.    //deprecation表示不对已经废弃的方法的使用进行警告   
  13.     public static void main(String[] args)   
  14.     {   
  15.         Map map = new TreeMap();   
  16.            
  17.         map.put("hello"new Date());   
  18.            
  19.         System.out.println(map.get("hello"));   
  20.            
  21.         Date date = new Date();   
  22.            
  23.         System.out.println(date.toLocaleString());   
  24.     }   
  25. }  

关于自定义注解

自定义注解:当注解中的属性名为value时,在对其赋值时可以不指定属性的名称而直接写上属性值即可;除了value以外的其他值都需要使用name=value这种赋值方式,即明确指定给谁赋值。
举例如下:
(1)先定义一个注解 

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. public @interface AnnotationTest   
  4. {   
  5.         //注解里定义属性要在属性后面加一个括号   
  6.     String[] value1() default "hello";//有一个默认值hello   
  7.     EnumTest value2(); //注解里面的值也可定义为枚举类型   
  8. }   
  9.   
  10. enum EnumTest   
  11. {   
  12.     Hello, World, Welcome;   
  13. }  

 注意:当一个接口继承Annotation接口时,该接口依然只是一个接口,还不是注解类型,
         要定义注解类型只有一种方式:通过@interface关键字,除此之外别无他法。
         另外,Annotation本身也只是一个接口,并不是注解类型(可以查看API文档有        Annotation这个接口)

(2)引用上面的注解 

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. @AnnotationTest(value2 = EnumTest.Welcome)   
  4. public class AnnotationUsage   
  5. {   
  6.     @AnnotationTest(value1 = {"world""ABCD"}, value2 = EnumTest.World)   
  7.     public void method()   
  8.     {   
  9.        System.out.println("usage of annotation");   
  10.     }   
  11.        
  12.     public static void main(String[] args)   
  13.     {   
  14.        AnnotationUsage usage = new AnnotationUsage();   
  15.            
  16.                    usage.method();   
  17.     }   
  18. }  

 

最后有一点需要注意的是:
当我们使用@interface关键字定义一个注解时,该注解隐含地继承了java.lang.annotation.Annotation接口;如果我们定义了一个接口,并且让该接口继承自Annotation,那么我们所定义的接口依然还是接口而不是注解;Annotation本身是接口而不是注解。可以与Enum类比。
 
 
 
第2集
 

本集主要讲述@Retention及@Target2个注解,顺带提一下@Documented这个注解

 

1.关于@Retention这个注解

Retention翻译成中文是“保留”的意思,RetentionPolicy是“保留策略”。

简要描述:指示注解类型的注解要保留多久。如果注解类型声明中不存在 Retention 注解,则保留策略默认为  RetentionPolicy.CLASS

每一个Retention都要给他一个RetentionType,RetentionType是一个枚举类型(具体可以查看API文档),它有3种取值:SOURCE,CLASS,RUNTIME,区别如下:

(a)SOURCE:表示该注解只会存在于JAVA源文件中,不会编译到class文件里面去,更不会在运行期通过反射的方式获   取到。

(b)CLASS:表示该注解会随着JAVA源代码一起编译到class文件里面去,但不会在运行期通过反射的方式获取到。

(c)RUNTIME:表示该注解会随着JAVA源代码一起编译到class文件里面去,并且会在运行期通过反射的方式获取到。

 

请看一个示例:

首先定义一个注解:

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. import java.lang.annotation.Retention;   
  4. import java.lang.annotation.RetentionPolicy;   
  5.   
  6.   
  7. //注解也可以修饰注解,该注解修饰下面自定义的注解,通过设定   
  8. //RetentionPolicy的值为RUNTIME表示该自定义的注解会被编   
  9. //译到CLASS文件当中,而且可以在运行期通过反射的方式获取到(具体请查看一遍API文档,很有必要!)   
  10. @Retention(RetentionPolicy.RUNTIME)   
  11. public @interface MyAnnotation   
  12. {   
  13.     String hello() default "shengsiyuan";   
  14.   
  15.     String world();   
  16. }  

然后定义一个类,用这个Annotation去修饰

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. @MyAnnotation(hello = "beijing", world = "shanghai")   
  4. public class MyTest   
  5. {          
  6.         //一个方法可以被多个注解所修饰。   
  7.     @MyAnnotation(hello = "tianjin", world = "shangdi")   
  8.     @Deprecated  
  9.     @SuppressWarnings("unchecked")    
  10.     public void output()   
  11.     {   
  12.         System.out.println("output something!");   
  13.     }   
  14. }  

 接着定义一个类,并通过反射相关API去获得自定义注解的相关信息

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. import java.lang.annotation.Annotation;   
  4. import java.lang.reflect.Method;   
  5.   
  6. //该类拿到修饰MyTest里方法的Annotation   
  7. public class MyReflection   
  8. {   
  9.     public static void main(String[] args) throws Exception   
  10.     {   
  11.         MyTest myTest = new MyTest();   
  12.            
  13.         Class<MyTest> c = MyTest.class;   
  14.            
  15.         Method method = c.getMethod("output"new Class[]{});   
  16.            
  17.                 //能够进入到if语句里面来说明MyAnnotation的RetentionPolicy的值为Runtime(为什么请查API文档!)   
  18.         if(method.isAnnotationPresent(MyAnnotation.class))   
  19.         {   
  20.             method.invoke(myTest, new Object[]{});   
  21.                
  22.             MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);   
  23.                
  24.             String hello = myAnnotation.hello();   
  25.             String world = myAnnotation.world();   
  26.                
  27.             System.out.println(hello + ", " + world);   
  28.         }   
  29.   
  30.         //只会得到Myannotation和Deprecated两个Annotation,因为只有这两个Annotation的RetentionPolicy   
  31.                 //的值为Runtime,只有RetentionPolicy的值为Runtime才会在运行期通过反射相关API拿到Annotation的相关信息。   
  32.         Annotation[] annotations = method.getAnnotations();   
  33.            
  34.         for(Annotation annotation : annotations)   
  35.         {   
  36.             System.out.println(annotation.annotationType().getName());   
  37.         }   
  38.     }   
  39. }  

 

2.关于@Target这个注解(建议去读一读API文档,介绍的很详细)

 简要描述:指示注解类型所适用的程序元素的种类。如果注解类型声明中不存在 Target 元注解,则声明的类型可以用在任一程序元素上。

每一个Target都要给他一个ElementType,ElementType是一个枚举类型(具体可以查看API文档),它有8种取值:SOURCE,CLASS,RUNTIME,区别如下:

(a)ANNOTATION_TYPE:表示该注解可以去修饰另外一个注解

(b)COUNSTRUCTOR:表示该注解可以修饰构造方法

(c)FIELD:表示该注解可以修饰成员变量

(d)LOCAL_VARIABLE:表示该注解可以修饰局部变量

(e)METHOD:表示该注解可以修饰普通方法

(f)PACKAGE:表示该注解可以修饰包

(g)PARAMETER:表示该注解可以修饰方法参数

(h)TYPE:表示该注解可以修饰类、接口(包括注解类型)或枚举声明

 

请看示例:

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. import java.lang.annotation.ElementType;   
  4. import java.lang.annotation.Target;   
  5.   
  6. @Target(ElementType.METHOD)//表示该自定义注解只能用于修饰方法   
  7. public @interface MyTarget   
  8. {   
  9.     String value();   
  10. }  

接着定义一个类:

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. public class MyTargetTest   
  4. {   
  5.     @MyTarget("hello")   
  6.     public void doSomething()   
  7.     {   
  8.         System.out.println("hello world");   
  9.     }   
  10. }  

 当把该自定义的注解放到方法上面后编译器不报错时,说明我们的实验是成功的(不需要写main方法进行测试)

 

对以上2个注解的总结:Retention与Target都是注解,Retention与RetentionPolicy搭配,Target与ElementType搭配。

 

3.关于@Documented(了解就行)

不多做描述,请看示例:

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. import java.lang.annotation.Documented;   
  4.   
  5. @Documented   //当一个注解被@Documented 修饰后表示被该注解修饰的对象(类或方法或其他)在生成JAVA DOC文档时,该注解会被加到修饰的对象的上面   
  6. public @interface DocumentedAnnotation   
  7. {   
  8.     String hello();   
  9. }  

 然后用该注解去修饰某个方法

Java代码 复制代码 收藏代码
  1. package com.shengsiyuan.annotation;   
  2.   
  3. public class DocumentedTest   
  4. {   
  5.     @DocumentedAnnotation(hello = "welcome")   
  6.     public void method()   
  7.     {   
  8.         System.out.println("hello world");   
  9.     }   
  10. }  

 当对DocumentedTest所在的包或工程生成JAVA DOC文档的时候,会发现自定义的注解会出现在method方法的上面

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多