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 @Target
2
3 public @interface 注解名{
4
5 }

@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={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={ElementType.FIELD})
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface Checked {
4     public boolean checked() default false;
5 }

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

1 @Target(value={ElementType.FIELD})
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface DateType {
4     public String format() default "yyyy-MM-dd";
5 }

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

定义一个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="性别", [email protected](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 }

定义一个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=null;
 31             // 日期要判断格式
 32             if(fields[i].getType()==Date.class || fields[i].getType()==java.sql.Date.class){
 33                 value=getDateString(fields[i], bean);
 34             }else {
 35                 try {
 36                     value=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=‘")
 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=null;
 74         try {
 75             value=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 }

最后是一个测试:

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=‘海淀西苑‘>

Java Annotation 学习

时间: 07-16

Java Annotation 学习的相关文章

学习笔记之Java Annotation学习总结 [ 光影人像 东海陈光剑 的博客 ]

?? 按照自己定的学习计划,今天是该写点什么了. ? 在上篇文章里提到的是JUnit的学习,其中就涉及到了一些内置的annotation,如@Test.@Ignore等.现在我就结合个人的理解谈下如何自定义自己的annotation. ? annotation能被用来为某个程序元素(类.方法.成员变量等)关联任何的信息,但annotaion不能影响程序代码的执行,无论增加.删除annotation,代码都始终如一的执行.另外,尽管一些annotation通过java的反射api方法在运行时被访问

Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这部分内容需要以下Jar包支持 mysql-connector:MySQL数据库连接驱动,架起服务端与数据库沟通的桥梁: MyBatis:一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架: log4j:Apache的开源项目,一个功能强大的日志组件,提供方便的日志记录: 修改后的pom.xm

java 注解 学习

周末闲来无事,想要研究一下注解方面的知识,以前看过几次,都忘记了,这次学习下,并且写篇文章记录下, 1.元注解  元注解是指注解的注解.包括 @Retention @Target @Document @Inherited四种. 1.1.@Retention: 定义注解的保留策略  Java代码 复制代码代码如下: @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含 @Retention(RetentionPolicy.CL

Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 记录: 通过对用户表的管理,更加深入地讲解SpringMVC的操作. 6 用户管理 既然我们

Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)

本文是Java反射学习总结系列的最后一篇了,这里贴出之前文章的链接,有兴趣的可以打开看看. http://blog.csdn.net/a396901990/article/category/2302221 本文介绍了如何利用反射和注解去简单的模拟JUnit4单元测试框架,之所以选择JUnit4是因为4.0以后最大的改进就是使用了注解.需要注意的是这里并不是完全的模拟,只是简单实现了一下Runner类和JUnit注解相关的工作流程.所以本文的主要目的是介绍反射和注解的使用.废话不多说,直接进入正文

Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 Java EE 学习(8):IDEA + maven + spring 搭建 web(

回顾java Annotation(注解)

最近在学习中发现相当多的框架是通过注解来实现的.为了加深记忆,把注解重新做一下回顾. 首先注解不是注释.--但因为java语言内置了三个注解:@Override.@Deprecated.@SuppressWarnnings.第一个是通知编译器做方法覆盖检查:第二个是提醒程序员使用了过时的方法:第三个是通知编译器忽略警告.这三个内置注解用起来给人的感觉就象注释一样.而实际上注解的用法远不止这么简单,通过使用自定义注解有助于加深我们的理解. 使用自定义注解目的是为了给程序加上某些标记(这种标记也可称

Java开发学习心得(二):Mybatis和Url路由

Java开发学习心得(二):Mybatis和Url路由 序号接上一篇Java开发学习心得(一):SSM环境搭建 1.3 Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .MyBatis是一个基于Java的持久层框架.iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)MyBatis 消除了几

自己写的基于java Annotation(注解)的数据校验框架

JavaEE6中提供了基于java Annotation(注解)的Bean校验框架,Hibernate也有类似的基于Annotation的数据校验功能,我在工作中,产品也经常需要使 用数据校验,为了方便和重用,自己写了一个简单的基于Annotation的校验框架.有兴趣的可以扩展. 框架说明: AnnotationValidable接口:所有需要使用该校验框架的类都要实现它,该类中没有任何方法需要实现,仅仅是一个表明那些类需要使用该校验框架的标识. GetFiledValue类:是一个工具类,对