17.5反射与简单java类

本文介绍如何利用Java反射机制解决传统属性赋值的弊端,实现属性的自动赋值。通过自定义ClassInstanceFactory类和BeanUtils工具类,演示了如何根据传入的字符串结构动态创建对象并设置其属性值。

一、传统属性赋值弊端

class Emp {
	private String ename ;
	private String job ;
	// setter、getter略
}
public class JavaReflectDemo {
	public static void main(String[] args) throws Exception {
		Emp emp = new Emp() ;	// 实例化对象
		emp.setEname("SMITH"); // 属性设置
		emp.setJob("CLERK");	// 属性设置
		System.out.println("姓名:" + emp.getEname() + "、职位:" + emp.getJob());
	}
}

二、属性自动赋值实现思路

定义一个ClassInstanceFactory类负责所有的反射处理



public class ClassInstanceFactory {
	//实例化对象的创建方法,该对象可以根据传入的字符串结构 “属性:内容|属性:内容|...”
public static <T> T create(Class<?> clazz,String value) {
	return null;
}
}
  class JavaReflectDemo454{
	  public static void main(String[] args) {
		String value="name:xiaohei|age:5";
		Dog dog=ClassInstanceFactory.create(Dog.class, value);
		System.out.println("姓名:"+dog.getName()+"年龄:"+dog.getAge());
	}
  }




三、单级属性赋值

单级属性赋值是指简单java类之间没有任何的引用联系,这类操作只需要通过反射实例化对象,并根据属性找到相应的setter()方法,反射进行方法调用为属性赋值即可。
1、由于需要通过属性找到set方法,所以需要提供一个首字母大写的功能,为此定义一个字符串工具类。

package com.lxh.seventeenchapter;

public class StringUtils {
     /*
      * 实现字符串首字母大写,如果只有一个字母则直接将此字母大写
      * @param str要转换的字符串
      * @return 大写处理结果,如果传入的字符串为空则返回null
      */
	public static String initcap(String str) {
		if(str==null||"".equals(str)) {
			return str;
		}
		if(str.length()==1){     //判断字符串长度
			return str.toUpperCase();   //单个字母直接大写
		}else {                         //首字母大写
			return str.substring(0,1).toUpperCase()+str.substring(1);
		}
	}
}

2、定义BeanUtils工具类,通过该类实现setter方法的调用并进行属性赋值(String为例)

package com.lxh.seventeenchapter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BeanUtils {
       /*
        * 实现指定对象的属性设置
        * @param  obj要进行反射操作的数理化对象
        * @param value 包含指定内容的字符串,格式"属性:内容|属性:内容"
        * 
        */
	public static void setValue(Object obj,String value) {
		
		String results[]=value.split("\\|");//按照“|”对每一组属性进行拆分
		for (int i = 0; i < results.length; i++) {
			//attval[0]保存的属性名称,attval[1]保存属性内容
			String attval[]=results[i].split(":");
			try {
				Field field=obj.getClass().getDeclaredField(attval[0]);//获取成员
		     //根据成员名称拼出要使用的set方法,同时根据Field获取属性类型
				Method setMethod=obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attval[0],field.getType()));
				setMethod.invoke(obj, attval[1]);
			
			} catch (NoSuchFieldException | SecurityException e) {
			
				e.printStackTrace();
			}
		}
	}
}

3、ClassInstanceFactory负责调用BeanUtils类实现属性内容的赋值

public class ClassInstanceFactory {
	//实例化对象的创建方法,该对象可以根据传入的字符串结构 “属性:内容|属性:内容|...”
	
public static <T> T create(Class<?> clazz,String value) {
	//如果想要采用反射进行简单java类对象属性设置的时候,类中必须有无参构造
	try {
		Object obj=clazz.getDeclaredConstructor().newInstance();
		BeanUtils.setValue(obj, value);
		return (T)obj;    //返回对象
	} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
			| NoSuchMethodException | SecurityException e) {
	
		e.printStackTrace();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值