文档章节

注解(Annotation)--注解处理器

boonya
 boonya
发布于 2015/04/17 09:24
字数 1033
阅读 124
收藏 19

如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了。使用注解的过程中,很重要的一部分就是创建于使用注解处理器。Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器。


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

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

  一个简单的注解处理器:  

复制代码

/***********注解声明***************//**
 * 水果名称注解
 * @author peida
 * */@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic @interface FruitName {
    String value() default "";
}/**
 * 水果颜色注解
 * @author peida
 * */@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic @interface FruitColor {    /**
     * 颜色枚举
     * @author peida
     *     */
    public enum Color{ BULE,RED,GREEN};    
    /**
     * 颜色属性
     * @return
     */
    Color fruitColor() default Color.GREEN;

}/**
 * 水果供应者注解
 * @author peida
 * */@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic @interface FruitProvider {    /**
     * 供应商编号
     * @return
     */
    public int id() default -1;    
    /**
     * 供应商名称
     * @return
     */
    public String name() default "";    
    /**
     * 供应商地址
     * @return
     */
    public String address() default "";
}/***********注解使用***************/public class Apple {
    
    @FruitName("Apple")    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)    private String appleColor;
    
    @FruitProvider(id=1,name="陕西红富士集团",address="陕西省西安市延安路89号红富士大厦")    private String appleProvider;    
    public void setAppleColor(String appleColor) {        this.appleColor = appleColor;
    }    public String getAppleColor() {        return appleColor;
    }    
    public void setAppleName(String appleName) {        this.appleName = appleName;
    }    public String getAppleName() {        return appleName;
    }    
    public void setAppleProvider(String appleProvider) {        this.appleProvider = appleProvider;
    }    public String getAppleProvider() {        return appleProvider;
    }    
    public void displayName(){
        System.out.println("水果的名字是:苹果");
    }
}/***********注解处理器***************/public class FruitInfoUtil {    public static void getFruitInfo(Class<?> clazz){
        
        String strFruitName=" 水果名称:";
        String strFruitColor=" 水果颜色:";
        String strFruitProvicer="供应商信息:";
        
        Field[] fields = clazz.getDeclaredFields();        
        for(Field field :fields){            if(field.isAnnotationPresent(FruitName.class)){
                FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                strFruitName=strFruitName+fruitName.value();
                System.out.println(strFruitName);
            }            else if(field.isAnnotationPresent(FruitColor.class)){
                FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
                System.out.println(strFruitColor);
            }            else if(field.isAnnotationPresent(FruitProvider.class)){
                FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
                strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
                System.out.println(strFruitProvicer);
            }
        }
    }
}/***********输出结果***************/public class FruitRun {    /**
     * @param args     */
    public static void main(String[] args) {
        
        FruitInfoUtil.getFruitInfo(Apple.class);
        
    }

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

复制代码

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


本文转载自:http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

共有 人打赏支持
boonya
粉丝 73
博文 214
码字总数 43922
作品 0
成都
高级程序员
Java Annotation 简介

本文介绍了Java Annotation相关知识并附有相关的Demo。内容仅供参考使用,有不足之处请及时指出,也欢迎大家交流探讨。 Java Annotation 概述 Java Annotation翻译为Java 注解,注解也称为元...

村头细雨忆流年
08/28
0
0
Java注解(Annotation)详解

Java注解(Annotation)详解 1.Annotation的概念 An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may......

幻海流心
05/23
0
0
ButterKnife原理分析(二)注解的处理

上一篇我们讲解了ButterKnife的设计思想,理解了ButterKnife绑定相关源码的实现逻辑。但是它是怎么通过注解的方式生成的那些逻辑代码,这才是最让我们迫切想知道,因此在这篇,我将说说Butte...

Ihesong
2017/12/31
0
0
springmvc学习笔记(3)-注解的处理器映射器和适配器

springmvc学习笔记(3)-注解的处理器映射器和适配器 标签: springmvc [TOC] 本文主要介绍注解的处理器映射器和适配器相关配置 默认加载 前端控制器从件中加载处理器映射器、适配器、视图解析...

brianway
2016/03/09
124
0
java --注解

1.什么是注解? 注解也叫元数据(用来描述数据的数据),它用来对某些元素进行说明/注释等。 注解是一个接口,程序可以通过反射来获取指定元素的Annotaion,然后通过Annotation对象来获取注解里...

求是科技
2016/09/25
29
0

没有更多内容

加载失败,请刷新页面

加载更多

70.shell的函数 数组 告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析 20.16/20.17 shell中的函数: ~1. 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段...

王鑫linux
今天
2
0
分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
今天
6
0
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
今天
4
0
Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情。并发课题对于Java来说是一个又重要又难的一大块,除非气定神闲、精力满满,否则我本身是不敢随便写...

心中的理想乡
今天
40
0
shell学习之获取用户的输入命令read

在运行脚本的时候,命令行参数是可以传入参数,还有就是在脚本运行过程中需要用户输入参数,比如你想要在脚本运行时问个问题,并等待运行脚本的人来回答。bash shell为此提 供了read命令。 ...

woshixin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部