首页 > 代码库 > Java Annotation 学习

Java Annotation 学习

  Java中的注解的应用越来越广泛,测试框架JUnit4, 以及Spring,Hibernate,Struts,MyBatis,JPA等等都包含了对注解的支持。在C#中的Attribute特性就是和Java中的注解是对应的。使用注解是为了编程更简便。但是我们得知道注解是做什么的,最好是能够自己的代码中可以自定义注解,提高生产率。

  下面就来说一下Annotation,先说一下基本知识,然后用一个例子把这些串起来。

-------------------------------------------------------元注解----------------------------------------------------------------------------

  Java注解分类:元注解、一般的注解。元数据,是数据的数据,数据的信息。那么元注解同样道理,是注解的注解,注解的信息。java中的元注解有:@Retention @Target @Document @Inherited:

  @Document 是用于javadoc的。一般很少使用。

  @Retention: 定义注解的保留策略:

SOURCE :只是在源代码中保留。编译后的class文件中就不会有的。

CLASS:会保留到Class文件中,在类的加载器把类加载到JVM中,就会去掉了。

RUNTIME:保留至运行时,也就是可以在JVM中使用了。这种最常用。

 

@Target:定义注解的作用目标:

@Target(ElementType.TYPE)   //接口、类、枚举、注解

@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR)  //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包   

@Inherited 继承其他的注解

这些都元注解。

------------------------------------------------------------注解---------------------------------------------------------------------------

Annotation本身不是个注解,但是我们写的注解都会隐藏的继承这个类。

注解的声明:

1 @Retention @Target2 3 public @interface 注解名{4 5 }
View Code

@interface,用于表示注解。由interface知道注解中都是以接口的方式书写的,就是以接口中方法的书写方式书写。
注解中的方法,称为注解的元素。它的语法是:

public elementType elementName() [default value];

 

 

elementName, 元素名,命名方式就是java中方法的命名方式。

elementType ,元素的类型,可以使用的元素类型有:

  原生类型:byte,short,int,long,float,double

  字符串:String,

  日期:Date

  Class

  enum

可以设置默认值。

如何使用就不用说了。

对于注解的处理,是通过Java中的反射来的。

题外话:如果没有反射,就没有Java中的各种框架。可见反射多么的重要。

 

-----------------------------------------------------示例--------------------------------------------------------------------------------

设计一个Input注解,用于将Java bean中属性输出成HTML中的Input元素。这个是我即是写的,没有什么实际意义,但是用于说明注解,就够用了,它包括了注解的各种用法:

Input注解:

 1 @Target(value=http://www.mamicode.com/{ElementType.FIELD}) 2 @Retention(RetentionPolicy.RUNTIME) 3 public @interface Input { 4     public String value() default "";        // 元素是普通类型 5     public String style() default ""; 6     public String clazz() default ""; 7     public String id() default ""; 8     public String title() default ""; 9     public String volidator() default "";10     public Checked checked() default @Checked(checked=false);    // 元素是注解11     public InputType type() default InputType.text;                // 元素是枚举12     13     14     enum InputType {15         text, radio, checkbox, button, password, file;16     }17 }
Input注解
1 @Target(value=http://www.mamicode.com/{ElementType.FIELD})2 @Retention(RetentionPolicy.RUNTIME)3 public @interface Checked {4     public boolean checked() default false;5 }
View Code

上面这两个类定义了两个注解,Checked注解又是作为Input注解的元素的。

1 @Target(value=http://www.mamicode.com/{ElementType.FIELD})2 @Retention(RetentionPolicy.RUNTIME)3 public @interface DateType {4     public String format() default "yyyy-MM-dd";5 }
View Code

这个注解,是一个日期类型的注解。

定义一个Java bean,使用上面定义的三个注解:

 1 public class Person { 2      3     @Input(title="编号") 4     private int id; 5     @Input(title="姓名") 6     private String name; 7     @Input(title="年龄") 8     private int age; 9     @Input(title="出生日期")10     @DateType(format="yyyy-MM-dd HH:mm:ss")11     private Date birthday;12     @Input(title="地址")13     private String address;14     @Input(title="性别", checked=@Checked(checked=true))15     private String gender;16     @Input(title="口令", type=InputType.password)17     private String password;18     19     public String getGender() {20         return gender;21     }22     public void setGender(String gender) {23         this.gender = gender;24     }25     public int getId() {26         return id;27     }28     public void setId(int id) {29         this.id = id;30     }31     public String getName() {32         return name;33     }34     public void setName(String name) {35         this.name = name;36     }37     public int getAge() {38         return age;39     }40     public void setAge(int age) {41         this.age = age;42     }43     public Date getBirthday() {44         return birthday;45     }46     public void setBirthday(Date birthday) {47         this.birthday = birthday;48     }49     public String getAddress() {50         return address;51     }52     public void setAddress(String address) {53         this.address = address;54     }55     56     57 }
View Code

 

定义一个Writer,处理上面的注解,:

  1 package com.fjn.tools.annotation;  2   3 import java.io.PrintWriter;  4 import java.lang.reflect.Field;  5 import java.util.Date;  6 /**  7  * 包装PrintWriter  8  */  9 import com.fjn.tools.common.DateHelper; 10 @SuppressWarnings("rawtypes") 11 public class BeanWriter<T> extends PrintWriter{ 12     private PrintWriter out; 13     private T bean; 14     public BeanWriter(PrintWriter out) { 15         super(out); 16         this.out=out; 17     } 18      19     public void write(){ 20         if(bean==null) return; 21          22         Class clazz=bean.getClass(); 23         Field[] fields=clazz.getDeclaredFields(); 24         StringBuffer sbf=new StringBuffer();; 25         for (int i = 0; i < fields.length; i++) { 26          27             Input input=fields[i].getAnnotation(Input.class); 28             if(input == null) continue; 29             fields[i].setAccessible(true); 30             Object value=http://www.mamicode.com/null; 31             // 日期要判断格式 32             if(fields[i].getType()==Date.class || fields[i].getType()==java.sql.Date.class){ 33                 value=http://www.mamicode.com/getDateString(fields[i], bean); 34             }else { 35                 try { 36                     value=http://www.mamicode.com/fields[i].get(bean); 37                 } catch (Exception e1) { 38                     e1.printStackTrace(); 39                 } 40             } 41              42             sbf.append("<input type=‘") 43                 .append(input.type().name()) 44                 .append("‘ name=‘") 45                 .append(fields[i].getName()) 46                 .append("‘ id=‘") 47                 .append(input.id()) 48                 .append("‘ style=‘") 49                 .append(input.style()) 50                 .append("‘ title=‘") 51                 .append(input.title()) 52                 .append("‘ validator=‘") 53                 .append(input.volidator()) 54                 .append("‘ class=‘") 55                 .append(input.clazz()) 56                 .append("‘ value=http://www.mamicode.com/‘") 57                 .append(value). 58             append("‘>"); 59             out.write(sbf.toString()); 60             out.flush(); 61             sbf.delete(0, sbf.length()); 62         } 63     } 64      65     private String getDateString(Field field, Object bean){ 66         DateType dateType=field.getAnnotation(DateType.class); 67         String pattern=null; 68         if(dateType==null){ 69             pattern="yyyy-MM-dd"; 70         }else 71             pattern=dateType.format(); 72         field.setAccessible(true); 73         String value=http://www.mamicode.com/null; 74         try { 75             value=http://www.mamicode.com/DateHelper.parseString((Date)field.get(bean), pattern); 76         } catch (IllegalArgumentException e) { 77             // TODO Auto-generated catch block 78             e.printStackTrace(); 79         } catch (IllegalAccessException e) { 80             // TODO Auto-generated catch block 81             e.printStackTrace(); 82         } 83         return value; 84     } 85  86     public PrintWriter getOut() { 87         return out; 88     } 89  90     public void setOut(PrintWriter out) { 91         this.out = out; 92     } 93  94     public T getBean() { 95         return bean; 96     } 97  98     public void setBean(T bean) { 99         this.bean = bean;100     }101     102     103 }
View Code

最后是一个测试:

package com.fjn.tools.annotation.test;import java.io.PrintWriter;import java.util.Date;import com.fjn.tools.annotation.BeanWriter;import com.fjn.tools.annotation.Person;public class InputTest {    public static void main(String[] args) {        Person person=new Person();        person.setAddress("海淀西苑");        person.setAge(25);        person.setName("张三");        person.setId(23);        person.setBirthday(new Date());                BeanWriter<Person> inputWriter=new BeanWriter<Person>(new PrintWriter(System.out));        inputWriter.setBean(person);                inputWriter.write();    }}

感兴趣的朋友可以拿去执行以下这段代码。

上面的代码执行结果:

<input type=‘text‘ name=‘id‘ id=‘‘ style=‘‘ title=‘编号‘ validator=‘‘ class=‘‘ value=‘23‘><input type=‘text‘ name=‘name‘ id=‘‘ style=‘‘ title=‘姓名‘ validator=‘‘ class=‘‘ value=‘张三‘><input type=‘text‘ name=‘age‘ id=‘‘ style=‘‘ title=‘‘ validator=‘‘ class=‘‘ value=‘25‘><input type=‘text‘ name=‘birthday‘ id=‘‘ style=‘‘ title=‘‘ validator=‘‘ class=‘‘ value=‘2014-07-17 12:26:15‘><input type=‘text‘ name=‘address‘ id=‘‘ style=‘‘ title=‘‘ validator=‘‘ class=‘‘ value=‘海淀西苑‘>