黑马程序员_Java Annotation学习

来源:互联网 发布:类似萝莉云的软件 编辑:程序博客网 时间:2024/05/01 15:05

                                             ------- android培训java培训、期待与您交流!----------

   从Java5.0版发布以来,5.0平台提供了一个正式的annotation功能:允许开发者定义、使用自己的
annotation类型。此功能由一个定义annotation类型的语法和一个描述annotation声明的语法,读取
annotation的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。   
annotation并不直接影响代码语义,但是它能够工作的方式被看作类似程序的工具或者类库,它会反过来
对正在运行的程序语义有所影响。annotation可以从源文件、class文件或者以在运行时反射的多种方式
被读取。
当然annotation在某种程度上使javadoc tag更加完整。一般情况下,如果这个标记对java文
档产生影响或者用于生成java文档的话,它应该作为一个javadoc tag;否则将作为一个annotation。   
JDK5提供的几个常用Annotation
  Override  
  Deprecated
  SuppressWarnings
  1)、限定Override父类方法@Override    java.lang.Override是个Marker annotation
用于标示的Annotation,Annotation名称本身即表示了要给工具程序的信息

  2)、标示方法为Deprecated @Deprectated
    对编译程序说明某个方法已经不建议使用,即该方法是过时的。
java.lang.Deprecated也是个Marker annotation
   Deprecated这个名称在告知编译程序,被@Deprecated标示的方法是一个不建议被使用的方法 


 3)、抑制编译程序警告@SuppressWarnings
  自定义Annotation类型:
  定义Marker Annotation,也就是Annotation名称本身即提供信息
对于程序分析工具来说,主要是检查是否有MarkerAnnotation的出现,并作出对应的动作
   value成员设定默认值,用"default"关键词
数组方式的使用枚举在Annotation中的应用   使用@interface自行定义Annotation型态时,实际上是自动继承了java.lang.annotation.Annotation接口
由编译程序自动为您完成其它产生的细节
在定义Annotation型态时,不能继承其它的Annotation型态或是接口   定义Annotation型态时也可以使用包来管理类别
方式类同于类的导入功能
   下面介绍几种Annotation的用法


   一、告知编译程序如何处理@Retention
   java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您
的自定义的Annotation型态
预设上编译程序会将Annotation信息留在.class档案中,但不被虚拟机读取
,而仅用于编译程序或工具程序运行时提供信息   在使用Retention型态时,需要提供

java.lang.annotation.RetentionPolicy的枚举型态
package java.lang.annotation;
public enum 
RetentionPolicy
 {
   SOURCE, //编译程序处理完Annotation信息后就完成任务
   CLASS,  //编译程序将Annotation储存于class档中,缺省
   RUNTIME //编译程序将Annotation储存于class檔中,可由VM读入
}
  RetentionPolicy为SOURCE的例子是@SuppressWarnings
仅在编译时期告知编译程序来抑制警告,所以

不必将这个信息储存于.class档案
RetentionPolicy为RUNTIME的时机,可以像是您使用Java设计一个程
序代码分析工具,您必须让VM能读出Annotation信息,以便在分析程序时使用
搭配反射(Reflection)机制,就可以达到这个目的   java.lang.reflect.AnnotatedElement接口

public Annotation 
getAnnotation(Class annotationType);
public Annotation[] getAnnotations();
public Annotation[] getDeclaredAnnotations();
public boolean isAnnotationPresent(Class annotationType);

Class、Constructor、Field、Method、Package等类别,都实现了AnnotatedElement接口定义
Annotation时必须设定RetentionPolicy为RUNTIME,也就是可以在VM中读取Annotation信息
参见程序
 使用@Retention的例子:

package com.my.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
String hello() default "hello";
String world();
}

测试类:
package com.my.annotation.test;
@MyAnnotation(hello = "beijing", world = "shanghai")
public class MyTest
{
@MyAnnotation(hello = "beijing", world = "shanghai")
@Deprecated
@SuppressWarnings("unchecked")
public void output()
{
System.out.println("output something");
}
}

二、限定annotation使用对象@Target
   使用java.lang.annotation.Target可以定义其使用之时机
在定义时要指定

java.lang.annotation.ElementType的枚举值之一
package java.lang.annotation;public enum 
ElementType 
{
  
    TYPE, //适用class, interface, enum
 
    FIELD, //适用field
    METHOD, //适用method
    PARAMETER, //适用method上之parameter 
    CONSTRUCTOR, //适用constructor
    LOCAL_VARIABLE, //适用局部变量
    ANNOTATION_TYPE, //适用annotation型态
    PACKAGE //适用package
}

@Target使用例子:
package com.my.annotation;
import java.lang.annotation.*;
public @interface MyTarget
{
String value();
}
测试类:
package com.langsin.annotation;
public class MyTargetTest
{
@MyTarget("xyz")
public void doSomething()
{
System.out.println("hello world");
}
}

  三、要求为API文件@Documented

  想要在使用者制作JavaDoc文件的同时,也一并将Annotation的讯息加入至API文件中
使用

java.lang.annotation.Documented
   一个使用@Documented的小例子:
  package com.my.annotation;
import java.lang.annotation.Documented;
@Documented
public @interface DocumentedAnnotation
{
String hello();
}

测试类:
package com.my.annotation.text;
public class DocumentedTest
{
@DocumentedAnnotation(hello = "welcome")
public void method()
{
System.out.println("hello world");
}
}

  四、 子类是否继承父类@Inherited
   预设上父类别中的Annotation并不会被继承至子类别中
可以在定义Annotation型态时加上
java.lang.annotation.Inherited型态的Annotation。事实上,Inherated在JDK5中还没有发生作用

    使用@Inherited的例子:


package com.my.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedTest
{
String value();
}

package com.my.annotation;
@InheritedTest("parent")
public class Parent
{
public void doSomething()
{
System.out.println("hello");
}
}

package com.my.annotation;
public class Child extends Parent
{

}

测试类:
package com.my.annotation.test;
public class Test
{
public static void main(String[] args)
{
Class<Parent> c = Parent.class;

if(c.isAnnotationPresent(InheritedTest.class))
{
InheritedTest inheritedTest = c.getAnnotation(InheritedTest.class);

String value = inheritedTest.value();
System.out.println(value);
}
}
}


                                       ------- android培训java培训、期待与您交流!----------

                                 详情请查看:http://edu.csdn.net/heima