`

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 反射实例,大量注释,简单易懂"这个主题的详细解释: 1. **反射基础**: - Java反射API主要由`java.lang.reflect`包提供,包括`Class`,`Constructor`,`Method`和`Field`等类。 - `Class`类代表...

    java反射经典实例

    在本“Java反射经典实例”中,我们将深入探讨这个主题,了解如何利用反射来访问和修改私有属性以及调用私有方法。 1. **反射的概念与用途** - 反射机制是在运行时分析类的能力,它允许我们获取类的信息(如类名、...

    java反射实例代码

    在提供的"java反射实例代码"中,应该包含了如何使用上述方法的实际示例,这些示例有助于加深对Java反射机制的理解。通过阅读和运行这些代码,开发者可以更直观地学习如何在程序运行时动态地操作类、方法和字段,从而...

    Java 8个反射实例

    以下将详细介绍Java反射的8个关键实例。 1. 获取Class对象 要使用反射,首先需要获取到目标类的Class对象。这可以通过以下几种方式实现: - 使用`Class.forName()`方法,如`Class&lt;?&gt; clazz = Class.forName("全...

    Java反射实例源码

    标题"Java反射实例源码"表明我们将探讨如何通过源代码来实现和理解Java反射。这个实例可能包含了如何动态地创建对象、调用方法、访问字段和执行构造器的示例。 描述中提到的博客文章"菜鸟学编程(九)——Java反射...

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

    关于Java反射的实例,我们可以创建一个简单的例子。假设我们有一个接口`Service`和两个实现类`ServiceImpl1`、`ServiceImpl2`。在不使用反射的情况下,我们通常会通过new关键字创建服务对象。而通过反射,可以在运行...

    Java反射实例

    以下是对"Java反射实例"的详细解释: 1. **获取Class对象** 要使用反射,首先需要获取到对应的`Class`对象。这可以通过以下三种方式实现: - 使用`Class.forName()`方法,传入类的全名(包括包名)。 - 对象的`...

    220个JAVA初学者实例

    以上只是Java初学者实例中可能涉及的部分关键知识点,通过220个实例的实践,你可以逐步建立起扎实的Java基础,为后续深入学习和项目开发打下坚实的基础。不断地练习和巩固这些知识,将有助于你成长为一名合格的Java...

    java反射应用实例

    在标题“Java反射应用实例”中,我们关注的是如何在实际项目中利用反射来实现特定的功能。这篇博客文章(可以通过链接访问)可能会探讨以下几个方面: 1. **什么是反射**:首先,我们需要理解反射的基本概念。反射...

    java反射实例

    7. **注解与反射**:通过`getAnnotations()`和`isAnnotationPresent()`等方法,可以获取类、方法、字段上的注解信息,这对于实现元数据驱动的设计非常有用。 8. **动态代理(Dynamic Proxy)**:Java反射还提供了`...

    Java 注解Annotation实例上手文档

    Java注解(Annotation)自JDK 5.0引入以来,已经成为Java语言的重要特性之一,它为代码元数据提供了一种标准化的方式,使得编译器、工具和其他框架能够理解和处理这些元数据。在Java中,注解是一种元数据,可以被...

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

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

    Java基础编程实例

    Java基础编程实例是Java初学者入门的绝佳资源,它涵盖了Java语言的核心概念和技术。这个教程旨在帮助新手理解并掌握Java编程的基本元素,从而能够独立编写简单的程序。以下是一些主要的知识点: 1. **Java环境配置*...

    注解+ 反射实例demo

    在Java编程语言中,注解(Annotation)和反射(Reflection)是两个强大的特性,它们极大地扩展了代码的可读性和动态性。注解是一种元数据,可以为编译器、工具或运行时系统提供信息,而反射则允许程序在运行时检查类...

    java学习小实例

    8. **反射与注解**:反射允许程序在运行时检查和操作类、接口和对象。注解提供了一种元数据方式,可以用来标记代码,供编译器或运行时系统使用。 9. **泛型**:泛型引入了类型参数,增强了代码的类型安全性和可读性...

    java的反射机制的应用实例

    以下是对Java反射机制应用实例的详细解释: 1. **获取类信息**:使用`Class`类的`forName()`方法可以获取到任何类的`Class`对象,例如`Class&lt;?&gt; clazz = Class.forName("全限定类名");`。这样我们就能获取到该类的...

    Java IOC及反射api代码参考实例

    Spring框架通过反射来实例化bean,并根据配置的依赖关系进行注入。例如,当定义了一个带有@Autowired注解的字段时,Spring会利用反射找到合适的依赖并注入到该字段中。 下面是一些关于Java IOC和反射API的关键知识...

    15个经典的java课程设计实例.rar

    14. **反射与注解**:通过反射动态调用方法和访问字段,理解注解的使用和自定义注解的创建。 15. **单元测试**:学习JUnit,编写测试用例,确保代码的正确性。 每一个实例都是一个独立的学习点,通过实践这些实例...

    利用java反射、注解及泛型模拟ORM实现

    在Java编程中,反射、注解(Annotation)和泛型是三个非常重要的特性,它们各自在不同的场景下发挥着关键作用。这篇博文“利用java反射、注解及泛型模拟ORM实现”旨在探讨如何结合这三种技术来实现对象关系映射(ORM...

Global site tag (gtag.js) - Google Analytics