Java 注解

来源:互联网 发布:淘宝女童鞋品牌大全 编辑:程序博客网 时间:2024/05/01 21:36

  Annotation(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。
  Annotation( 注解 )是JDK5.0及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。从某些方面看,annotation就像修饰符一样被使用,并应用于包、类、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在Annotation的“key=value”键值对中。
  基本的规则:Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。
  Annotation的行为十分类似public、final这样的修饰符。每个Annotation具有一个名字和>=0成员个数。每个Annotation的成员具有被称为key=value对的名字和值(就像javabean一样),key=value装载了Annotation的信息。也就是说注解中可以不存在成员个数

Annotation类型
  Annotation类型定义了Annotation的名字、类型、成员默认值。一个Annotation类型可以说是一个特殊的java接口,它的成员变量是受限制的,而声明Annotation类型时需要使用新语法。当我们通过java反射访问Annotation时,返回值将是一个实现了该annotation类型接口的对象,通过访问这个对象我们能方便的访问到其Annotation成员。

注解的分类

根据注解参数的个数,我们可以将注解分为三类:
1. 标记注解:一个没有成员定义的注解类型被称为标记注解,如@Override;
2. 单值注解:成员个数为1;
3. 完整注解:成员个数>1

根据注解使用方法和用途,我们可以将Annotation分为三类:

1. 内置系统注解

  • @Override
      用途:写一个父类,让子类实现其方法。若把父类中的方法删除掉,注解就会报错。
      @Override说明此方法覆盖了父类的方法,是一个标记注解类型,它被用作标注方法,起到了断言(assert)的作用。如果我们使用了这种Annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时发挥威力。使用方法极其简单:在使用此annotation时只要在被修饰的方法前面加上@Override即可。

  • @Deprecated
    用途:在父类或者子类的方法上写该注解,表明该方法已经过时。(只是支持方法标记?)
      同样Deprecated也是一个标记注解。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。而且这种修饰具有一定的 “延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。

  • @SuppressWarnings
    用途:用于通知java编译器禁止特定的编译警告。被用于有选择地关闭编译器对类、方法、成员变量、变量初始化的警告。

2. 元注解

元注解的作用就是负责解释说明其他注解。

  • @Target
      @Target说明了Annotation所修饰的对象范围,注解可被用于packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
    作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
    取值(ElementType)有:
       1.CONSTRUCTOR:用于描述构造器
       2.FIELD:用于描述域
       3.LOCAL_VARIABLE:用于描述局部变量
       4.METHOD:用于描述方法
       5.PACKAGE:用于描述包
       6.PARAMETER:用于描述参数
       7.TYPE: 用于描述类、接口(包括注解类型) 或enum声明
  • @Retention
      @Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对Annotation的”LifeCycle”进行限制。
    作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
    取值(RetentionPoicy)有:
      1.SOURCE: 在源文件中有效(即源文件保留)
      2.CLASS: 在class文件中有效(即class保留)
      3.RUNTIME: 在运行时有效(即运行时保留)
      
  • @Documented
    生成文档的时候使用

  • @Inherited
      @Inherited元注解是一个标记注解, @Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
      注意:@Inherited注解仅是被标注过的class的子类所继承,类并不从它所实现的接口继承此annotation,方法并不从它所重载的方法继承此annotation。
      当@Inherited注解标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

3. 自定义注解

定义注解的格式:

public @interface AnnotationName {}

注解参数的可支持数据类型:

  1. 所有基本数据类型(byte, short, int, long, float, double, boolean, char)
  2. String类型
  3. Class类型
  4. enum类型
  5. Annotation类型
  6. 以上所有类型的数组

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

Annotation类型里面的参数该怎么设定:
  第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   
  第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
  第三,如果只有一个参数成员,最好把参数名称设为”value”,后加小括号.例:下面的例子FruitName注解就只有一个参数成员。

注解的处理器

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

0 0
原创粉丝点击