JavaAnnotation与枚举

JavaAnnotation,枚举与反射的使用

Annotation的由来:

JAVA应用中,我们常遇到一些需要使用模板代码的情况,例如,为了编写一个web service,我们必须提供一对接口和实现作为模板代码。如果使用annotation对远程访问代码进行修饰的话,这个模板就能够使用工具自动生成。

另外,一些API需要使用与程序代码同时维护的附属文件,例如EJB需要一个部署描述符,此时在程序中使用annotation来维护这些附属文件的信息将十分便利而且减少了错误。

Java5.0版本发布以来,5.0平台提供了一个正式的annotation功能:允许开发者定义、使用自己的annotation类型。此功能由一个定义annotation类型的语法和一个描述annotation声明的语法,读取annotationAPI,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。

annotation并不直接影响代码的语义,但是它能够工作的方式被看做类似程序的工具或者类库,它会反过来对正在运行的程序语义有所影响。annotation可以从源文件,class文件或者以运行时反射的多种方式被读取。

当然annotation在某种程度上使javadoc tag更加完整,一般情况下,如果这个标记对java文档产生影响或者用于生成java文档的话,它应该作为一个javadoc tag;否则将作为一个annotation.

使用JDK5.0内建的Annotation

@Override  @Deprecated  @SuppressWarnings

java.lang.Override是个Marker annotation是用于标示的Annotation,Annotation名称本身即表示了要给工具程序的信息。

对编译程序说明某个方法已经不建议使用,即该方法是过时的。java.lang.Depreacted也是个Marker annotation.

Deprecate这个名称告知编译程序,被Deprecated指示的方法是一个不建议使用的方法。

@SuppressWarnings

对编译程序说明某个方法中若有警告讯息,则加以抑制。

自定义Annotation

定义Marker Annotation,也就是Annotation名称本身提供信息,对于程序分析工具来说,主要是检查是否有Marker Annotation的出现,并作出对应的动作。

value成员设定默认值,用“default”关键字

数组方式的使用, 枚举在Annotation中的应用。

使用@interface 自行定义Annotation形态时,实际上是自动继承了java.lang.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读入

}

RetentionPolicySOURCE的例子是@SuppressWarnings

仅在编译时期告知编译程序来抑制警告,所以不必将这个信息存储于.class档案。

RetentionPolicyRUNTIME的时机,可以像是您使用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时,必须设置RetentionPolicyRUNTIME, 也就是可以在VM中读取Annotation信息。

package com.test.factory;

 

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

 

@Retention(RetentionPolicy.RUNTIME)

public @interface MyAnnotation {

   

    String hello() default "linxin";

   

    String world();

 

}

 

 

package com.test.factory;

 

public class MyTest {

   

    @MyAnnotation(hello="beijing", world="tai")

    public void output() {

       System.out.println("MyTest");

    }

 

}

 

 

package com.test.factory;

 

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

 

public class MyReflectionTest {

   

    public static void main(String[] args) throws Exception {

      

       Class<MyTest> c = MyTest.class;

      

       Method method = c.getMethod("output", new Class[]{});

      

       if (method.isAnnotationPresent(MyAnnotation.class)) {

           MyAnnotation a = method.getAnnotation(MyAnnotation.class);

           System.out.println(a.hello());

           System.out.println(a.world());

           method.invoke(c.newInstance(), new Class[]{});

          

       }

      

       Annotation[] a = method.getAnnotations();

      

       for (Annotation b : a) {

           System.out.println(b.annotationType().getName());

       }

      

    }

 

}

限定annotation使用对象@Target

使用java.lang.annotation.Target可以定义其使用之时机

在定义时要指定java.lang.annotation.ElementType的枚举值之一。

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

预设上父类别中的Annotation并不会被继承至子类别中

可以在定义Annotation形态时加上

java.lang.annotation.Inherited形态的Annotation

事实上InheritedJDK1.5中没有发生作用。

Java枚举

 

package lyb;

 

public class Enumeration1 {

   

    // 私有的构造方法

    private Enumeration1() {}

   

    public static final Enumeration1 SUN

                  = new Enumeration1() {

       @Override

       public Enumeration1 nextDay() {

           return SAT;

       }

    } ;

   

    public static final Enumeration1 SAT

                  = new Enumeration1() {

       @Override

       public Enumeration1 nextDay() {

           return SUN;

       }

    };

   

    public Enumeration1 nextDay() {

       /*if (this == Enumeration1.SAT) {

           return Enumeration1.SUN;

       } else {

           return Enumeration1.SAT;

       }*/

       return null;

    }

   

    @Override

    public String toString() {

       return (this == Enumeration1.SAT) ? "SAT" : "SUN";

    }

 

}

 

package lyb;

 

import java.util.Date;

 

public class TestEnum {

 

    public static void main(String[] args) {

       Enumeration1 e = Enumeration1.SAT;

       System.out.println(e.nextDay());

       Enumeration2 e2 = Enumeration2.MON;

       System.out.println(e2);

       System.out.println(Enumeration2.valueOf("MON"));

      

       Enumeration2[] es = Enumeration2.values();

      

       for (Enumeration2 enumeration2 : es) {

           System.out.println(enumeration2);

       }

       System.out.println(e2.name());

       System.out.println(e2.ordinal());

       System.out.println(es.length);

       new Date(300) {

          

       };

      

       new Runnable() {

           public void run() {

              // TODO Auto-generated method stub

             

           }

       };

    }

   

    public enum Enumeration2 {

      

       // 注意此处时子类实例化

       MON{

          

       }, TUES(), WED, THUR, FRI, SAT, SUN;

      

       private Enumeration2() {

           System.out.println("first");

       }

      

        private Enumeration2(int i) {

           System.out.println("second");

       }

    }

 

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值