您的位置:首页 > 编程语言 > Java开发

JDK5.0新特性(2)-注解(Annotation)

2011-06-26 21:27 363 查看
Annotation就是注解。

在J2SE中,内置的Annotation 内置的有三种1.@Override 2. @Deprecated 3.@SuppressWarnings("unchecked") 这种是不检查警告

当然我们也可以自定义注解,需要注意以下几点:
1.当注解中的属性值为value时,在使用并对其赋值的时候可以不指定属性名称而直接写上属性值即可,除了value以外的其他值都需要使用@MyAnnotation(xxx="xxx") 的方式,从而明确指定给谁赋值,
2.我们还可以为注解设置默认值,就是我们对参数不指定参数时的值使用default关键字
3.使用@interface自行定义Annotation型态时,实际上是自动继承(隐含的)了java.lang.annotation.Annotation接口,编译程序自动为你完成其他产生的细节,在定义Annotation型态时,不能继承其它的Annotation型态或者是接口。
4.如果一个interface手动的extends Annotation,那么这个interface其实还是接口而不是注解。定义注解必须是@interface
5.在定义Annotation的型态时,不能够继承其他的Annotation型态或者接口。

我们也可以Annotation的Retention
1.什么是Retention。java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的Annotation,它其实也是个Annotation类型。缺省情况下编译程序会将Annotation信息留在档案中,但是不能被 虚拟机读取,而仅用于编译程序或者工具程序运行时提供信息。
2.在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的枚举型态 ,有三个枚举常量:CLASS、
RUNTIME、SOURCE,默认是RetentionPlicy.CLASS。RetentionPolicy为SOURCE的例子是@suppressWarnings 这时候仅是在编译的时候来抑制警告,而不必把这个信息存于class档案中去。RetentionPolicy为RUNTIME的时机,可以是像你用JAVA设计了一个程序代码工具,您必须让VM能读出Annotation信息, 以便在分析程序时使用,搭配反射机制就可以实现上述功能。我们通过文档可以发现,Deprecated是的Retention的value是RUNNTIME类型的,所以我们可以使用反射来得到 注解。

我们还能限定Annotation的Target

使用这个注解可以定义Annotation的使用时机,在定义时要指定Java.lang.annotation.ElementType的枚举之一(这个和Retentpolicy有相似之处)

写个了例子:

?[Copy to clipboard]Download TestAnnotation.java

/**
* TestAnnotation.java
* annotation
*
* Function: TODO
*
*   ver     date           author
* ──────────────────────────────────
*           2011-6-20      Leon
*
* Copyright (c) 2011, TNT All Rights Reserved.
*/

package annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* ClassName:TestAnnotation
* Function:
* 测试Java内置的Annotation 内置的有三种1.@Override  2. @Deprecated
* 3.@SuppressWarnings("unchecked")  这种是不检查警告
* Reason:   TODO ADD REASON
*
* @author   Leon
* @version
* @since    Ver 1.1
* @Date     2011-6-20
*/
@MyAnnotation(value2=EnumTest.Hello) //第一个是默认赋值
public class TestAnnotation {

@SuppressWarnings({"unchecked" , "deprecated"})
public static void main(String...  args) throws Exception{
List list=new ArrayList();
list.add("aa");
Date date = new Date();

//通过反射来得到 Annotation 这时候我们必须把Retention设置为Runtime类型
TestRetention  testRetention = new TestRetention();
Class<testretention> c = TestRetention.class;
Method method = c.getMethod("output"); // 第二个是可变参数 如果没有那就不输入
//如果这个method使用了这个Annotation
if(method.isAnnotationPresent(MyRetentPolicyTest.class)){
method.invoke(testRetention);

MyRetentPolicyTest myAnnotation =method.getAnnotation(MyRetentPolicyTest.class);

String hello = myAnnotation.hello();
String world = myAnnotation.world();

System.out.println(hello + ",  " + world);

Annotation[]  anntations = method.getAnnotations();
for(Annotation  annotation : anntations){
//得到的Annotation和RetentionPolicy是有关的,必须是RUNTIME才返回
System.out.println(annotation.annotationType().getName());
}
}

}

@Override
public String toString() {

// TODO Auto-generated method stub
return super.toString();

}
@Deprecated
public void deprecated(){

}

}
/**
*
* MyAnnotation  自定义注解
* 2011-6-20 下午03:57:40
*
* @version 1.0.0
* 1.当注解中的属性值为value时,在使用并对其赋值的时候可以不指定属性名称而直接写上属性值即可,
* 除了value以外的其他值都需要使用@MyAnnotation(xxx="xxx") 的方式,从而明确指定给谁赋值,
* 2.我们还可以为注解设置默认值,就是我们对参数不指定参数时的值使用default关键字
* 3.使用@interface自行定义Annotation型态时,实际上是自动继承(隐含的)了java.lang.annotation.Annotation接口,
*   由编译程序自动为你完成其他产生的细节,在定义Annotation型态时,不能继承其它的Annotation型态或者是接口
* 4.如果一个interface手动的extends Annotation,那么这个interface其实还是接口而不是注解。定义注解必须是@interface
* 5.在定义Annotation的型态时,不能够继承其他的Annotation型态或者接口
*
*/

@interface MyAnnotation{
//添加一个字符串类型
String value() default "hello" ;
//添加一个枚举类型
EnumTest value2();

}
/**
*
* EnumTest
* 2011-6-25 下午05:03:26
*
* @version 1.0.0
* 同时我们还可以使用Enum作为注解值
*
*/
enum EnumTest{
Hello , World , Welcome ;
}

/**
*  1.什么是Retention
*  java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的
*  Annotation,它其实也是个Annotation类型。缺省情况下编译程序会将Annotation信息留在档案中,但是不能被
*  虚拟机读取,而仅用于编译程序或者工具程序运行时提供信息.
*  2.在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的枚举型态 ,有三个枚举常量:CLASS、
*  RUNTIME、SOURCE,默认是RetentionPlicy.CLASS.
*  RetentionPolicy为SOURCE的例子是@suppressWarnings 这时候仅是在编译的时候来抑制警告,而不必把这个信息存于
*  .class档案中去。
*  RetentionPolicy为RUNTIME的时机,可以是像你用JAVA设计了一个程序代码工具,您必须让VM能读出Annotation信息,
*  以便在分析程序时使用,搭配反射机制就可以实现上述功能。我们通过文档可以发现,Deprecated是的Retention的value是
*  RUNNTIME类型的,所以我们可以使用反射来得到 注解。
*/

@Documented    //只有定义了这个标志,在生成文档时才能把这个注解添加在文档中
@Retention(RetentionPolicy.RUNTIME)  //这个就表示这个注解被编译到Class中但是不会在JVM运行期间所读取到
@interface  MyRetentPolicyTest{
String  hello() default "zuiniuwang" ;
String  world();
}
//一个类或者一个方法可以被多个注解修饰
/**
*  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接口
*/
@MyRetentPolicyTest(hello="zuiniuwang",world="test")

//@MyTarget   不允许修饰类
class  TestRetention{
@MyRetentPolicyTest(hello="zuiniuwang",world="test")
@Deprecated
@MyTarget
public void output(){
System.out.println("test  Annotation.....");
}

}

/**
* 限定annotation使用对象的@target
* 使用这个注解可以定义Annotation的使用时机,在定义时要指定Java.lang.annotation.ElementType
* 的枚举之一(这个和Retentpolicy有相似之处)
*
*/
@Target(ElementType.METHOD)  //定义此注解只能修饰方法
@interface MyTarget{
String value() default "aa";
}

/**
* 预设中父类的Annotation并不会被继承至子类别中,如果需要继承则需要再Annotation型态上时加上
* java.lang.annotation.Inherited型态的Annotation
*/

</testretention>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息