`

java 注解反射实例

    博客分类:
  • java
阅读更多

Java注解反射实例

主要功能:

1. 得到一个类的所有注解信息

2. 通过注解信息实例化一个类

 

实体类:

1. 注解类

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到  
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法  
@Documented //说明该注解将被包含在javadoc中
public @interface FieldMeta {
	
	/**
	 * 是否国序列号
	 * @return
	 */
	boolean id() default false;
	
	
	/**
	 * 字段名称
	 * @return
	 */
	String name() default "";
	
	/**
	 * 值
	 * @return
	 */
	String value() default "";
	
	
	/**
	 * 字段描述
	 * @return
	 */
	String description() default "";
	
	/**
	 * 排序字段
	 * @return
	 */
	int order() default 0;
}

 2. 包含注解的实体类

import java.util.Date;

public class Anno {

	@FieldMeta(id=true,name="序列号",value="1",order=1)
	private int id;
	@FieldMeta(name="姓名",value="Matt",order=3)
	private String name;
	@FieldMeta(name="年龄",value="12",order=2)
	private int age;
	@FieldMeta(name="出生日期",value="1999-08-12 12:12:12",order=4)
	private Date date;
	
	public Anno() {
		super();
	}

	public Anno(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	@FieldMeta(description="描述",order=4)
	public String desc(){
		return "java反射获取annotation的测试";
	}

	@Override
	public String toString() {
		return "Anno [id=" + id + ", name=" + name + ", age=" + age + ", date=" + date + "]";
	}

	
	
}

 3. 处理注解的类

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public abstract class BasicAnnoHannlder<T> {
	private Class<T> entity;
	private String dateFormat = "yyyy-MM-dd HH:mm:ss";
	public BasicAnnoHannlder(){}
	
	/**
	 * 实例化T对象
	 * @return
	 */
	public T init2(){
		entity = (Class<T>) ((ParameterizedType)this.getClass().getGenericSuperclass())  
                .getActualTypeArguments()[0];  
		try {
			//得到构造方法得到对象并赋值
			Constructor<T> constructor = entity.getConstructor();
			T instance = constructor.newInstance();
			setFilds(instance);
			return instance;
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		return null;
		
	}

	/**
	 * 得到所有的注解信息
	 * @return
	 */
	@SuppressWarnings("unchecked")  
    public List<SortableField> init(){  
        List<SortableField> list = new ArrayList<SortableField>();  
        /**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void) 
         * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。 
         *  getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 
         *  [0]就是这个数组中第一个了。。 
         *  简而言之就是获得超类的泛型参数的实际类型。。*/  
        entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass())  
                .getActualTypeArguments()[0];  
          
        if(this.entity!=null){  
              
            /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段 
             * entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段 
             * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等; 
             * 可看API 
             * */  
            Field[] fields = entity.getDeclaredFields();         
//            
            for(Field f : fields){  
            	
                //获取字段中包含fieldMeta的注解  
                FieldMeta meta = f.getAnnotation(FieldMeta.class);  
                if(meta!=null){  
                	//System.out.println(meta+"\tName:" + f.getName() + "\tType:" + f.getType());
                    SortableField sf = new SortableField(meta, f);  
                    list.add(sf);  
                }  
            }  
              
            //返回对象所表示的类或接口的所有可访问公共方法  
            Method[] methods = entity.getMethods();  
              
            for(Method m:methods){  
                FieldMeta meta = m.getAnnotation(FieldMeta.class);  
                if(meta!=null){
                	//System.out.println(meta + "\tName:" + m.getName() +"\tType:"+ m.getReturnType());
                    SortableField sf = new SortableField(meta,m.getName(),m.getReturnType());  
                    list.add(sf);  
                }  
            }  
            //这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序  
            Collections.sort(list, new Comparator<SortableField>() {  
                public int compare(SortableField s1,SortableField s2) {  
                    return s1.getMeta().order()-s2.getMeta().order();  
//                  return s1.getName().compareTo(s2.getName());//也可以用compare来比较  
                }  
                  
            });  
        }  
        return list;  
          
    }  
	
	private T setFilds(T t) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ParseException{
		Field[] fields = t.getClass().getDeclaredFields(); // 获取实体类的所有属性,返回Field数组
		
		for(int i=0;i < fields.length;i++){   // 遍历所有属性
			String name = fields[i].getName();  // 获取属性的名字
			name = name.substring(0, 1).toUpperCase() + name.substring(1); // 将属性的首字符大写,方便构造get,set方法
			
			
			String type = fields[i].getGenericType().toString(); //获取属性的类型
			String value = fields[i].getAnnotation(FieldMeta.class).value(); //获取属性注解的value值
			
			//根据类型反射给field赋值
			if(type.equals("class java.lang.String")){
				Method m = t.getClass().getMethod("set"+name,String.class);
				m.invoke(t, value);
			}
			else if (type.equals("class java.lang.Integer")) {
				Method m = t.getClass().getMethod("set"+name,Integer.class);
				m.invoke(t, Integer.parseInt(value));
			 }
			else if(type.equals("int")){
				Method m = t.getClass().getMethod("set"+name,int.class);
				m.invoke(t, (int)Integer.parseInt(value));
			}
			else if(type.equals("class java.util.Date")){
				Method m = t.getClass().getMethod("set"+name,Date.class);
				Date date = new SimpleDateFormat(dateFormat).parse(value);
				m.invoke(t, date);
			}
			
			// 如果有需要,可以仿照上面继续进行扩充,再增加对其它类型的判断
		}
		
		return t;
	}
	
}  

 4. 处理注解的子类

//传递Anno.class给父类
public class AnnoHannlder extends BasicAnnoHannlder<Anno>{

}

 5. 保存注解信息的类

import java.lang.reflect.Field;

public class SortableField {

	private FieldMeta meta;
	private Field field;
	private String name;
	private Class<?> type;
	
	
	public SortableField() {}


	public SortableField(FieldMeta meta, Field field) {
		super();
		this.meta = meta;
		this.field = field;
	}


	public SortableField(FieldMeta meta,String name, Class<?> type) {
		super();
		this.meta = meta;
		this.name = name;
		this.type = type;
	}


	public FieldMeta getMeta() {
		return meta;
	}


	public void setMeta(FieldMeta meta) {
		this.meta = meta;
	}


	public Field getField() {
		return field;
	}


	public void setField(Field field) {
		this.field = field;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public Class<?> getType() {
		return type;
	}


	public void setType(Class<?> type) {
		this.type = type;
	}


	@Override
	public String toString() {
		return "SortableField [meta=" + meta + ", field=" + field + ", name=" + name + ", type=" + type + "]";
	}
	
	

}

 6. 测试类

import java.util.List;

public class TestAnnotation {

	    public static void main(String[] args) {  
	        BasicAnnoHannlder<Anno> c = new AnnoHannlder();  
	    
	        List<SortableField> list = c.init();//获取泛型中类里面的注解  
	        //输出结果  
	        for(SortableField l : list){  
	            System.out.println(l);        
	        }  
	        
	        //通过注解得到对象
	        Anno anno = c.init2();
	        System.out.println(anno+ "\n"+ anno.desc());
	    }  
}

 

测试结果:

SortableField [meta=@com.gson.demo.anno.FieldMeta(summary=true, editable=true, name=序列号, description=, id=true, value=1, order=1), field=private int com.gson.demo.anno.Anno.id, name=null, type=null]
SortableField [meta=@com.gson.demo.anno.FieldMeta(summary=true, editable=true, name=年龄, description=, id=false, value=12, order=2), field=private int com.gson.demo.anno.Anno.age, name=null, type=null]
SortableField [meta=@com.gson.demo.anno.FieldMeta(summary=true, editable=true, name=姓名, description=, id=false, value=Matt, order=3), field=private java.lang.String com.gson.demo.anno.Anno.name, name=null, type=null]
SortableField [meta=@com.gson.demo.anno.FieldMeta(summary=true, editable=true, name=出生日期, description=, id=false, value=1999-08-12 12:12:12, order=4), field=private java.util.Date com.gson.demo.anno.Anno.date, name=null, type=null]
SortableField [meta=@com.gson.demo.anno.FieldMeta(summary=true, editable=true, name=, description=描述, id=false, value=, order=4), field=null, name=desc, type=class java.lang.String]
Anno [id=1, name=Matt, age=12, date=Thu Aug 12 12:12:12 CST 1999]
java反射获取annotation的测试

 

 

分享到:
评论

相关推荐

    java 反射实例,大量注释,简单易懂

    一个java反射的例子,通过java反射机制,动态生成java实例,动态执行方法。例子中有大量注释,简单易懂。

    java反射实例代码

    一个java普通工程,反射的所有方法和实例都有,,另外还有注释,可以帮助理解

    通过Java反射机制获取JavaBean对象

    1.通过Java反射机制获取JavaBean对象。 2.通过JavaBean全路径字符串获取JavaBean对象。 3.获取JavaBean注解信息

    Spring IOC 原理 ,Java 反射实例,自定义注解

    NULL 博文链接:https://zyqwst.iteye.com/blog/2255560

    Java 自定义注解及利用反射读取注解的实例

    下面小编就为大家带来一篇Java 自定义注解及利用反射读取注解的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java基础 反射篇.md

    Java基础 反射篇 - Java基础 反射篇 - 反射的思想及作用 - 反射的基本使用 - 获取类的 Class 对象 - 构造类的实例化对象 - 获取一个类的所有信息 - 获取类中的变量(Field) - 获取类中的方法(Method) - ...

    Java使用注解和反射简化编程的方法示例

    主要介绍了Java使用注解和反射简化编程的方法,结合实例形式分析了java使用注解和反射调用大量函数简化编程的相关操作技巧,需要的朋友可以参考下

    《剑指offer》Java基础-反射篇.pdf

    Java基础 反射篇 反射的思想及作用 反射的基本使用 获取类的 Class 对象 构造类的实例化对象 获取一个类的所有信息 获取类中的变量(Field) 获取类中的方法(Method) 获取类的构造器(Constructor) 获取注解 通过...

    最简单java 反射原理示例

    本实例是一个最简单的 Java 反射实例 ,分步介绍 和综合介绍 加注释的 希望能与大家交流

    Java高级程序设计实战教程第三章-Java反射机制.pptx

    对于任意一个对象,都能够调用它的任意一个方法,常见的应用如下 逆向代码 ,例如反编译 与注解相结合的框架 例如Retrofit 单纯的反射机制应用框架 例如EventBus 2.x 动态生成类框架 例如Gson Java高级程序设计实战...

    Java经典编程源码基础例程300.zip

    实例007 使用Eclipse注释代码 10 实例008 使用Eclipse格式化代码 11 实例009 安装WindowBuilder插件 12 实例010 开发计算器界面 14 第3章 Java语言基础 15 实例011 输出错误信息与调试信息 16 实例012 从控制台接收...

    Java的核心技术反射使用说明

    该例子以使用反射来完成实例化一个JFrame窗体的演示应用,说明Java的反射技术的一般使用。本示例,几乎一行一个注释,非常详细的说明了怎样使用反射,它是学习Java核心技术的非常好的例子。注意:本例子不适合初学...

    java注解之运行时修改字段的注解值操作

    主要介绍了java注解之运行时修改字段的注解值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    java深度历险

    JAVA注解 34 使用注解 34 开发注解 35 处理注解 35 实例分析 38 参考资料 39 JAVA反射与动态代理 40 基本用法 40 处理泛型 42 动态代理 42 使用案例 43 参考资料 44 JAVA I/O 45 流 45 缓冲区 47 字符与编码 48 通道...

    Java基于反射机制实现全部注解获取的方法示例

    主要介绍了Java基于反射机制实现全部注解获取的方法,结合实例形式分析了java反射机制获取注解的具体实现方法与操作注意事项,需要的朋友可以参考下

    java高手真经 光盘源码

    java高手真经 全光盘源代码 打包rar ...javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型编程 javaannotation.zip 28.Java注释符编程 javafeature.zip 29.Java5.0语言新特性

    Java利用自定义注解、反射实现简单BaseDao实例

    下面小编就为大家带来一篇Java利用自定义注解、反射实现简单BaseDao实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    达内Java培训-CoreJava全程笔记(WORD唐亮版)

    CoreJava DAY01 Java概述 1 ...CoreJava DAY16 反射、注释 57 CoreJava DAY17 GUI 64 CoreJava DAY18 awt event 81 CoreJava DAY19-20 多线程 85 CoreJava DAY21-22 IO 95 CoreJava DAY23 网络编程 107

Global site tag (gtag.js) - Google Analytics