java 注解

来源:互联网 发布:软件开发基础教程 编辑:程序博客网 时间:2024/05/10 03:53




一 元注解


@Documented
1.@Documented是一个标记注解--》没有成员。(标记注解:是一种特殊的注解,没有成员。只是一个声明  A marker annotation)

2.可以被文档化(用javadoc工具)

@Target
1.注解修饰的对象 的范围---》packages,types(类、接口、枚举、Annotation类型),类型成员(方法、构造方法、成员变量、枚举值),方法参数和本地变量(如循环变量、catch参数)

2.可以更加清楚的其该修饰什么目标

@Retention
retention:保留
表示在什么样的级别保留该注释信息

1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)

@Inherited
inherited继承

1.他是一个标记注解
2.表示某个被标注的类型是可以被继承的
3.如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类
4.注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。


二 Java自带的几个注解

Override
Deprecated
SupressWarnings


三 自定义注解

定义注解格式:
注解格式:
public @interface 注解名『
     定义体



定义体:
1.修饰符只能用public 或default修饰(没写则是default)

2.参数成员只能用基本类型
byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String; 

3.如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。



例子:
/**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}



/**
* 水果颜色注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 颜色枚举
     * @author peida
     *
     */
    public enum Color{ BULE,RED,GREEN};
    
    /**
     * 颜色属性
     * @return
     */
    Color fruitColor() default Color.GREEN;

}


注解的获取与处理

读取和使用注解---》创建与使用注解处理器(Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器)

1.
Annotation---》所有注解的父接口

2.
AnnotatedElement---》可以接受注解的程序元素。(该接口位于java.lang.reflect 包下)该接口主要有以下实现类:
Class:类定义
Constructor:构造器定义
Field:累的成员变量定义
Method:类的方法定义
Package:类的包定义

java.lang.reflect---》该包下有很多工具(实现反射功能)(有的可以读取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():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
  
解析注解:
     运行时:
          运行时 注解解析:

可手动调用下面常用 API 解析

1.
method.getAnnotation(AnnotationName.class);
(表示得到该 Target 某个 Annotation 的信息)

2.
method.getAnnotations();
(表示得到该 Target 所有 Annotation)

3.
method.isAnnotationPresent(AnnotationName.class);
(该 Target 是否被某个 Annotation 修饰)

例子:
```Class cls = Class.forName("cn.trinea.java.test.annotation.App");
        for (Method method : cls.getMethods()) {
            MethodInfo methodInfo = method.getAnnotation(
MethodInfo.class);
            if (methodInfo != null) {
                System.out.println("method name:" + method.getName());
                System.out.println("method author:" + methodInfo.author());
                System.out.println("method version:" + methodInfo.version());
                System.out.println("method date:" + methodInfo.date());
```



     编译时:
          
编译时 注解解析:
---》由编译器自动解析
---》a. 自定义类继承自                     AbstractProcessor
---》b. 重写其中的 process 函数
(实际是编译器在编译时自动查找所有继承自 AbstractProcessor 的类,然后调用他们的 process 方法去处理)


例子:
```
@SupportedAnnotationTypes({ "cn.trinea.java.test.annotation.MethodInfo" })
public class MethodInfoProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        HashMap<String, String> map = new HashMap<String, String>();
        for (TypeElement te : annotations) {
            for (Element element : env.getElementsAnnotatedWith(te)) {
                MethodInfo methodInfo = element.getAnnotation(MethodInfo.class);
                map.put(element.getEnclosingElement().toString(), methodInfo.author());
            }
        }
        return false;
    }
}

SupportedAnnotationTypes 表示这个 Processor 要处理的 Annotation 名字。
process 函数中参数 annotations 表示待处理的 Annotations,参数 env 表示当前或是之前的运行环境
process 函数返回值表示这组 annotations 是否被这个 Processor 接受,如果接受后续子的 rocessor 不会再对这个 Annotations 进行处理



```

  
  
  
  
  

0 0