@Retention定义了该Annotation被保留的时间长短有3中RetentionPolicy.SOURCE源文件有效,RetentionPolicy.CLASS:在class文件中有效,RetentionPolicy.RUNTIME:在运行时有效。

要想注解解析工具或编译器对其进行解析,就需要指定注解在编译期或运行期有效。

在运行期要使用注解,是通过Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据

(某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)

注解处理器类库(java.lang.reflect.AnnotatedElement)

Java使用java.lang.annotation.Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素,该接口主要有如下几个实现类:

  Class:类定义
  Constructor:构造器定义
  Field:累的成员变量定义
  Method:类的方法定义
  Package:类的包定义

  java.lang.reflect 包下主要包含一些实现反射功能的工具类,实际上,java.lang.reflect 包所有提供的反射API扩充了读取运行时Annotation信息的能力。当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。
  AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:

  方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
  方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
  方法3:boolean isAnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
  方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

程序通过反射获取了某个类的AnnotatedElement对象之后,使用上面的4个方法访问Annotation信息

  1. Field[] fields = clazz.getDeclaredFields();
  2. for(Field field :fields){
  3. if(field.isAnnotationPresent(FruitName.class)){
  4. //...

Field类

  1. public final
  2. class Field extends AccessibleObject implements Member {

AccessibleObject

  1. public class AccessibleObject implements AnnotatedElement {
  2. //...

示例:一个简单的自定义注解及注解处理器对该注解的解析

1、水果的名称、颜色、供应商注解

  1. package com.dxz.annotation.demo4;
  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. /**
  10. * 水果名称注解
  11. */
  12. @Target(ElementType.FIELD)
  13. @Retention(RetentionPolicy.RUNTIME)
  14. @Documented
  15. public @interface FruitName {
  16. String value() default "";
  17. }
  18. package com.dxz.annotation.demo4;
  19.  
  20. import java.lang.annotation.Documented;
  21. import java.lang.annotation.ElementType;
  22. import java.lang.annotation.Retention;
  23. import java.lang.annotation.RetentionPolicy;
  24. import java.lang.annotation.Target;
  25.  
  26. /**
  27. * 水果颜色注解
  28. */
  29. @Target(ElementType.FIELD)
  30. @Retention(RetentionPolicy.RUNTIME)
  31. @Documented
  32. public @interface FruitColor {
  33. /**
  34. * 颜色枚举
  35. * @author peida
  36. *
  37. */
  38. public enum Color{ BULE,RED,GREEN};
  39.  
  40. /**
  41. * 颜色属性
  42. * @return
  43. */
  44. Color fruitColor() default Color.GREEN;
  45.  
  46. }
  47.  
  48. package com.dxz.annotation.demo4;
  49.  
  50. import java.lang.annotation.Documented;
  51. import java.lang.annotation.ElementType;
  52. import java.lang.annotation.Retention;
  53. import java.lang.annotation.RetentionPolicy;
  54. import java.lang.annotation.Target;
  55.  
  56. /**
  57. * 水果供应者注解
  58. */
  59. @Target(ElementType.FIELD)
  60. @Retention(RetentionPolicy.RUNTIME)
  61. @Documented
  62. public @interface FruitProvider {
  63. /**
  64. * 供应商编号
  65. *
  66. * @return
  67. */
  68. public int id() default -1;
  69.  
  70. /**
  71. * 供应商名称
  72. *
  73. * @return
  74. */
  75. public String name() default "";
  76.  
  77. /**
  78. * 供应商地址
  79. *
  80. * @return
  81. */
  82. public String address() default "";
  83. }

2、使用注解(标注注解)

  1. package com.dxz.annotation.demo4;
  2.  
  3. import com.dxz.annotation.demo4.FruitColor.Color;
  4.  
  5. public class Apple {
  6.  
  7. @FruitName("Apple")
  8. private String appleName;
  9.  
  10. @FruitColor(fruitColor = Color.RED)
  11. private String appleColor;
  12.  
  13. @FruitProvider(id = 1, name = "陕西红富士集团", address = "陕西省西安市延安路89号红富士大厦")
  14. private String appleProvider;
  15.  
  16. public void setAppleColor(String appleColor) {
  17. this.appleColor = appleColor;
  18. }
  19.  
  20. public String getAppleColor() {
  21. return appleColor;
  22. }
  23.  
  24. public void setAppleName(String appleName) {
  25. this.appleName = appleName;
  26. }
  27.  
  28. public String getAppleName() {
  29. return appleName;
  30. }
  31.  
  32. public void setAppleProvider(String appleProvider) {
  33. this.appleProvider = appleProvider;
  34. }
  35.  
  36. public String getAppleProvider() {
  37. return appleProvider;
  38. }
  39.  
  40. public void displayName() {
  41. System.out.println("水果的名字是:苹果");
  42. }
  43. }

3、解析器解析

  1. package com.dxz.annotation.demo4;
  2.  
  3. import java.lang.reflect.Field;
  4.  
  5. public class FruitInfoUtil {
  6. public static void getFruitInfo(Class<?> clazz){
  7.  
  8. String strFruitName=" 水果名称:";
  9. String strFruitColor=" 水果颜色:";
  10. String strFruitProvicer="供应商信息:";
  11.  
  12. Field[] fields = clazz.getDeclaredFields();
  13.  
  14. for(Field field :fields){
  15. if(field.isAnnotationPresent(FruitName.class)){
  16. FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
  17. strFruitName=strFruitName+fruitName.value();
  18. System.out.println(strFruitName);
  19. }
  20. else if(field.isAnnotationPresent(FruitColor.class)){
  21. FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
  22. strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
  23. System.out.println(strFruitColor);
  24. }
  25. else if(field.isAnnotationPresent(FruitProvider.class)){
  26. FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
  27. strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
  28. System.out.println(strFruitProvicer);
  29. }
  30. }
  31. }
  32. }

测试类:

  1. package com.dxz.annotation.demo4;
  2.  
  3. public class Test {
  4.  
  5. public static void main(String[] args) {
  6. FruitInfoUtil.getFruitInfo(Apple.class);
  7. }
  8.  
  9. }

结果:

  1. 水果名称:Apple
  2. 水果颜色:RED
  3. 供应商编号:1 供应商名称:陕西红富士集团 供应商地址:陕西省西安市延安路89号红富士大厦

  Java注解的基础知识点(见下面导图)基本都过了一遍,下一篇我们通过设计一个基于注解的简单的ORM框架,来综合应用和进一步加深对注解的各个知识点的理解和运用。

Annotation之三:自定义注解示例,利用反射进行解析的更多相关文章

  1. Java注解Annotation与自定义注解详解

    Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...

  2. [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门

    转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...

  3. Java注解教程:自定义注解示例,利用反射进行解析

    Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入 ...

  4. 深入JAVA注解(Annotation):自定义注解 (转)

    原文出自:http://blog.csdn.net/yjclsx/article/details/52101922 一.基础知识:元注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义 ...

  5. 深入理解Java:注解(Annotation)自定义注解入门

    转载:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...

  6. 【转】深入理解Java:注解(Annotation)自定义注解入门

    http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的me ...

  7. Java注解(Annotation)自定义注解入门

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

  8. Java:注解(Annotation)自定义注解入门

    转载地址:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的 ...

  9. 注解(Annotation)自定义注解入门

    摘自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...

随机推荐

  1. Amazon SES介绍 - SES发送邮件的过程

     Amazon SES,  全称Amazon Simple Email Service,即Amazon简单邮件服务,它是Amazon提供的一款供开发人员或公司企业用来处理邮件相关业务的服务,也就是说, ...

  2. linux安装-----源码安装步骤--zlib软件安装

    该zlib 可以对许多其他软件的编译代码起着优化 压缩作用. 解压压缩包: .tar.gz------------->tar zxvf 压缩包.tar.gz .tar.bz2---------- ...

  3. python学习笔记(SMTP邮件发送)

    想着给框架添加邮件发送功能.所以整理下python下邮件发送功能 首先python是支持邮件的发送.内置smtp库.支持发送纯文本.HTML及添加附件的邮件 之后是邮箱.像163.qq.新浪等邮箱默认 ...

  4. python爬虫scrapy框架——爬取伯乐在线网站文章

    一.前言  1. scrapy依赖包: 二.创建工程 1. 创建scrapy工程: scrapy staratproject ArticleSpider 2. 开始(创建)新的爬虫: cd Artic ...

  5. [csharp] bool IsNumeric(Type type)

    /* "C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe" /out:IsNumericType.exe IsNumericType. ...

  6. MailJobUtils 发送邮件

    import java.util.List; import java.util.Properties; import javax.annotation.Resource; import javax.m ...

  7. Pro C/C++环境搭建

    一. 安装oracle软件或者oracle客户端. 二. 载入orasql10.lib (1)在连接器->常规->附件库目录中,加入orasql10.lib库所在目录. (2)在连接器-& ...

  8. Android 用户界面---定制组件(Custom Components)

    基于布局类View和ViewGroup的基本功能,Android为创建自己的UI界面提供了先进和强大的定制化模式.首先,平台包含了各种预置的View和ViewGroup子类---Widget和layo ...

  9. 【机器学习基石笔记】七、vc Dimension

    vc demension定义: breakPoint - 1 N > vc dimension, 任意的N个,就不能任意划分 N <= vc dimension,存在N个,可以任意划分 只 ...

  10. 解决AndroidStudio导入项目在 Building gradle project info 一直卡住

    Android Studio导入项目的时候,一直卡在Building gradle project info这一步,主要原因还是因为被墙的结果.gradle官网虽然可以访问,但是速度连蜗牛都赶不上.. ...