转 java annotation(注解)--入门

 

学习java的人都知道java中有javadoc这样的java注解,这类注解是用来生成帮助文档用的。

在EJB、Spring、Hibernate、Struts现都可用注解方式配置应用,但是我们对java annotation又有多少了解呢

其实annotation说是元数据(元数据大家应该不陌生--元数据 最本质、最抽象的定义为: data about data (关于数据的数据-- 关于数据的数据或者叫做用来描述数据的数据 )

 

元数据的作用

如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类:

l             编写文档:通过代码里标识的元数据生成文档。

l             代码分析:通过代码里标识的元数据对代码进行分析。

l             编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。

 

先看看怎么定义一个annotation

 

public @interface TestMethodAnnotation {  
      
}  
  

就是在定义接口的interface前加@

再看使用方法

 

@TestMethodAnnotation  
public String getName() {  
    return name;  
}  
  

添加变量

 

public @interface TestMethodAnnotation {  
    boolean serialize() default true;  
      
}  

 

@TestMethodAnnotation(serialize = false)  
public String getName() {  
    return name;  
}  

 

为变量赋默认值


public @interface TestMethodAnnotation {  
    boolean serialize() default true;  
      
}  
  

限定注释使用范围


     当我们的自定义注释不断的增多也比较复杂时,就会导致有些开发人员使用错误,主要表现在不该使用该注释的地方使用。为此,Java   提供了一个ElementType   枚举类型来控制每个注释的使用范围,比如说某些注释只能用于普通方法,而不能用于构造函数等。下面是Java   定义的ElementType   枚举:

 

public enum ElementType {  
    /** Class, interface (including annotation type), or enum declaration */  
    TYPE,  
    /** Field declaration (includes enum constants) */  
    FIELD,  
    /** Method declaration */  
    METHOD,  
    /** Parameter declaration */  
    PARAMETER,  
    /** Constructor declaration */  
    CONSTRUCTOR,  
    /** Local variable declaration */  
    LOCAL_VARIABLE,  
    /** Annotation type declaration */  
    ANNOTATION_TYPE,  
    /** Package declaration */  
    PACKAGE  
}  
  

添加使用范围

 

@Target(ElementType.METHOD)  
public @interface TestMethodAnnotation {  
    boolean serialize() default true;  
      
}  
  

这样表明该annotation只能用于方法注解

 

注释保持性策略

 

public enum RetentionPolicy {  
    /** 
     * Annotations are to be discarded by the compiler. 
     */  
    SOURCE,  
    /** 
     * Annotations are to be recorded in the class file by the compiler 
     * but need not be retained by the VM at run time.  This is the default 
     * behavior. 
     */  
    CLASS,  
    /** 
     * Annotations are to be recorded in the class file by the compiler and 
     * retained by the VM at run time, so they may be read reflectively. 
     * 
     * @see java.lang.reflect.AnnotatedElement 
     */  
    RUNTIME  
}  
  
CLASS 
          编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。即要通过java反射得到它是得不到的
RUNTIME 
          编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE 
          编译器要丢弃的注释。即要通过java反射得到它是得不到的

使用策略;

注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。

 

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface TestMethodAnnotation {  
    boolean serialize() default true;  
      
}  
  

运行时注解的读取


类类型注解

 

TestBean testbean = new TestBean();  
  
Class clazz = testbean.getClass();  
TestClassAnnotation testClassAnnotation = (TestClassAnnotation) clazz  
        .getAnnotation(TestClassAnnotation.class);  

 

方法类型注解

 

Method readMethod = prop.getReadMethod();  
                System.out.print(",readMethod:" + readMethod.getName());  
。。。。。。。。。。。。。。。  
                TestMethodAnnotation testAnnotation = readMethod  
                        .getAnnotation(TestMethodAnnotation.class);  
                if (testAnnotation != null) {  
                    System.out.println("serialize:"  
                            + testAnnotation.serialize());  
                }  
  

以下为完整的测试用例:

只能用于方法类型

 

package com.parkingfo.test.annotation;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface TestMethodAnnotation {  
    boolean serialize() default true;  
      
}  
  

只能用于类类型

 

package com.parkingfo.test.annotation;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface TestClassAnnotation {  
    String descript();  
}  
  

使用

 

package com.parkingfo.test;  
import com.parkingfo.test.annotation.TestClassAnnotation;  
import com.parkingfo.test.annotation.TestMethodAnnotation;  
@TestClassAnnotation(descript = "这是测试描述")  
public class TestBean extends Object {  
    private String name;  
    @TestMethodAnnotation(serialize = false)  
    public String getName() {  
        return name;  
    }  
    /** 
     * @param name 
     */  
    public void setName(String name) {  
        this.name = name;  
    }  
    @Override  
    public String toString() {  
        return super.toString();  
    }  
      
      
}  
  

测试类

 

package com.parkingfo.test;  
import java.beans.BeanInfo;  
import java.beans.IntrospectionException;  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.Method;  
import com.parkingfo.test.annotation.TestClassAnnotation;  
import com.parkingfo.test.annotation.TestMethodAnnotation;  
public class Test {  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        TestBean testbean = new TestBean();  
          
        Class clazz = testbean.getClass();  
        TestClassAnnotation testClassAnnotation = (TestClassAnnotation) clazz  
                .getAnnotation(TestClassAnnotation.class);  
          
        System.out.println(testClassAnnotation.descript());  
        BeanInfo beanInfo;  
        try {  
            beanInfo = Introspector.getBeanInfo(clazz);  
            PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();  
            for (PropertyDescriptor prop : props) {  
                String propName = prop.getName();  
                System.out.print("propterty:" + propName);  
                Method readMethod = prop.getReadMethod();  
                System.out.print(",readMethod:" + readMethod.getName());  
                Method writeMethod = prop.getWriteMethod();  
                if (writeMethod != null) {  
                    System.out.print(",writeMethod:" + writeMethod.getName());  
                }  
                System.out.println();  
                TestMethodAnnotation testAnnotation = readMethod  
                        .getAnnotation(TestMethodAnnotation.class);  
                if (testAnnotation != null) {  
                    System.out.println("serialize:"  
                            + testAnnotation.serialize());  
                }  
            }  
        } catch (IntrospectionException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
}  
  

测试类中用到了得到javabean信息的类Introspector的getBeanInfo(Class clazz)方法得到javabean的信息

 

 

 

转自http://blog.csdn.net/buyaore_wo/archive/2010/09/27/5909754.aspx

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值