首页 > 开发 > Java > 正文

学习教程:Java Annotation 高级应用

2024-07-13 09:55:29
字体:
来源:转载
供稿:网友

  前言:

  前不久在matrix上先后发表了《java annotation 入门》、《java annotation 手册》两篇文章,比较全面的对java annotation的语法、原理、使用三方面进行了阐述。由于《入门》中的简单例程虽然简单明了的说明了annotation用法,但给大家的感觉可能是意犹未见,所以在此行文《java annotation高级应用》,具体实例化解释annotation和annotation processing tool(apt)的使用。望能对各位的有所帮助。

  一、摘要:

  《java annotation高级应用》具体实例化解释annotation和annotation processing tool(apt)的使用。望能对各位的有所帮助。本文列举了用于演示annotation的brfw演示框架、演示apt的apt代码实例,并对其进行较为深度的分析,希望大家多多提意见。

  二、annotation实例分析

  1.brfw(beaninfo runtime framework)定义:

  本人编写的一个annotation功能演示框架。顾名思义,brfw就是在运行时取得bean信息的框架。

  2.brfw的功能:

  a.源代码级annotation:在bean的源代码中使用annotation定义bean的信息;

  b.运行时获取bean数据:在运行时分析bean class中的annotation,并将当前bean class中field信息取出,功能类似xdoclet;

  c.运行时bean数据的xml绑定:将获得的bean数据构造为xml文件格式展现。熟悉j2ee的朋友知道,这个功能类似jaxb.

  3.brfw框架:

  brfw主要包含以下几个类:

  a.persistent类:定义了用于修饰类的固有类型成员变量的annotation.

  b.exportable类:定义了用于修饰class的类型的annotation.

  c.exporttoxml类:核心类,用于完成brfw的主要功能:将具有exportable annotation的bean对象转换为xml格式文本。

  d.addressfortest类:被a和b修饰过的用于测试目的的地址bean类。其中包含了地址定义所必需的信息:国家、省级、城市、街道、门牌等。

  e.addresslistfortest类:被a和b修饰过的友人通讯录bean类。其中包含了通讯录所必备的信息:友人姓名、年龄、电话、住址(成员为addressfortest类型的arraylist)、备注。需要说明的是电话这个bean成员变量是由字符串类型组成的arraylist类型。由于朋友的住址可能不唯一,故这里的住址为由addressfortest类型组成的arraylist.

  从上面的列表中,可以发现a、b用于修饰bean类和其类成员;c主要用于取出bean类的数据并将其作xml绑定,代码中使用了e作为测试类;e中可能包含着多个d.

  在了解了这个简单框架后,我们来看一下brfw的代码吧!

  4.brfw源代码分析:

  a.persistent类:

  清单1:

package com.bjinfotech.practice.annotation.runtimeframework;

import java.lang.annotation.*;

/**
* 用于修饰类的固有类型成员变量的annotation
* @author cleverpig
*
*/
@retention(retentionpolicy.runtime)
@target(elementtype.field)
public @interface persistent {
        string value() default "";
}

  b.exportable类:

  清单2:

  package com.bjinfotech.practice.annotation.runtimeframework;

import java.lang.annotation.*;

/**
* 用于修饰类的类型的annotation
* @author cleverpig
*
*/
@retention(retentionpolicy.runtime)
@target(elementtype.type)
public @interface exportable {
        //名称
        string name() default "";
        //描述
        string description() default "";
        //省略name和description后,用来保存name值
        string value() default "";
        
}
  c.addressfortest类:

  清单3:

package com.bjinfotech.practice.annotation.runtimeframework;

/**
* 用于测试的地址类
* @author cleverpig
*
*/
@exportable("address")
public class addressfortest {
        //国家
        @persistent
        private string country=null;
        
        //省级
        @persistent
        private string province=null;
        
        //城市
        @persistent
        private string city=null;
        
        //街道
        @persistent
        private string street=null;

        //门牌
        @persistent
        private string doorplate=null;
        
        public addressfortest(string country,string province,
                        string city,string street,string doorplate){
                this.country=country;
                this.province=province;
                this.city=city;
                this.street=street;
                this.doorplate=doorplate;
        }
        
}

  d.addresslistfortest类:

  清单4:

  package com.bjinfotech.practice.annotation.runtimeframework;

import java.util.*;

/**
* 友人通讯录
* 包含:姓名、年龄、电话、住址(多个)、备注
* @author cleverpig
*
*/
@exportable(name="addresslist",description="address list")
public class addresslistfortest {
        //友人姓名
        @persistent
        private string friendname=null;
        
        //友人年龄
        @persistent
        private int age=0;
        
        //友人电话
        @persistent
        private arraylist telephone=null;
        
        //友人住址:家庭、单位
        @persistent
        private arraylist addressfortext=null;
        
        //备注
        @persistent
        private string note=null;
        
        public addresslistfortest(string name,int age,
                        arraylist telephonelist,
                        arraylist addresslist,
                        string note){
                this.friendname=name;
                this.age=age;
                this.telephone=new arraylist(telephonelist);
                this.addressfortext=new arraylist(addresslist);
                this.note=note;
                
        }
}
  e.exporttoxml类:

  清单5:

package com.bjinfotech.practice.annotation.runtimeframework;

import java.lang.reflect.field;
import java.util.collection;
import java.util.iterator;
import java.util.map;
import java.util.arraylist;

/**
* 将具有exportable annotation的对象转换为xml格式文本
* @author cleverpig
*
*/
public class exporttoxml {
        /**
         * 返回对象的成员变量的值(字符串类型)
         * @param field 对象的成员变量
         * @param fieldtypeclass 对象的类型
         * @param obj 对象
         * @return 对象的成员变量的值(字符串类型)
         */
        private string getfieldvalue(field field,class fieldtypeclass,object obj){
                string value=null;
                
                try{
                        if (fieldtypeclass==string.class){
                                value=(string)field.get(obj);
                        }
                        else if (fieldtypeclass==int.class){
                                value=integer.tostring(field.getint(obj));
                        }
                        else if (fieldtypeclass==long.class){
                                value=long.tostring(field.getlong(obj));
                        }
                        else if (fieldtypeclass==short.class){
                                value=short.tostring(field.getshort(obj));
                        }
                        else if (fieldtypeclass==float.class){
                                value=float.tostring(field.getfloat(obj));
                        }
                        else if (fieldtypeclass==double.class){
                                value=double.tostring(field.getdouble(obj));
                        }
                        else if (fieldtypeclass==byte.class){
                                value=byte.tostring(field.getbyte(obj));
                        }
                        else if (fieldtypeclass==char.class){
                                value=character.tostring(field.getchar(obj));
                        }
                        else if (fieldtypeclass==boolean.class){
                                value=boolean.tostring(field.getboolean(obj));
                        }
                }
                catch(exception ex){
                        ex.printstacktrace();
                        value=null;
                }
                return value;
        }
        
        /**
         * 输出对象的字段,当对象的字段为collection或者map类型时,要调用exportobject方法继续处理
         * @param obj 被处理的对象
         * @throws exception
         */
        public void exportfields(object obj) throws exception{
                exportable exportable=obj.getclass().getannotation(exportable.class);        
                if (exportable!=null){
                        if (exportable.value().length()>0){
//                                system.out.println("class annotation name:"+exportable.value());
                        }
                        else{
//                                system.out.println("class annotation name:"+exportable.name());
                        }
                }
                else{
//                        system.out.println(obj.getclass()+"类不是使用exportable标注过的");
                }
                
                //取出对象的成员变量
                field[] fields=obj.getclass().getdeclaredfields();
                
                for(field field:fields){
                        //获得成员变量的标注
                        persistent fieldannotation=field.getannotation(persistent.class);
                        if (fieldannotation==null){
                                continue;
                        }
                        //重要:避免java虚拟机检查对私有成员的访问权限
                        field.setaccessible(true);
                        class typeclass=field.gettype();
                        string name=field.getname();
                        string value=getfieldvalue(field,typeclass,obj);
                        
                        //如果获得成员变量的值,则输出
                        if (value!=null){
                                system.out.println(getindent()+"<"+name+">/n"
                                                +getindent()+"/t"+value+"/n"+getindent()+"");
                        }
                        //处理成员变量中类型为collection或map
                        else if ((field.get(obj) instanceof collection)||
                                        (field.get(obj) instanceof map)){
                                exportobject(field.get(obj));
                        }
                        else{
                                exportobject(field.get(obj));
                        }
                        
                }
        }
        
        //缩进深度
        int leveldepth=0;
        //防止循环引用的检查者,循环引用现象如:a包含b,而b又包含a
        collectioncyclicchecker=new arraylist

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表