java 编写实例化instanll_Java反射(二)实现简单对象的实例化和属性设置

将之前学的Java知识进行汇总和整理,本篇主要讲述Java反射和使用用例。

项目开发中,经常遇到需要给实例化对象设置属性值,并且当属性特别多时,setter属性占用很大篇幅,在此用反射实现实例化对象,并自动设置属性值。可以作为以后项目的小工具,方便开发。

大致思路:(1)对需要实例化的Class对象,通过反射进行实例化;(2)将固定格式的参数注入到对象中。

篇外话:该思路与Spring的IOC类似,(1)程序启动时,Spring会解析提前配置好的Bean信息(如通过XML配置或注解配置),将Bean抽象为BeanDefinition结构,其中包含类的全限定名和依赖的类信息,并注册到容器中(说白了就是key-value的map中)。(2)在程序第一次执行getBean()时,会注入依赖的对象,这个会设计级联注入,直到属性为基本类型。

开始正文,下边代码是实现了类的实例化和属性设置功能,主要包括 简单数据类型设置 和 级联对象引用设置。

(1)创建类实例化工厂类:包含实例化和设置属性值两个步骤;

(2)StringUtils类用于处理setter和getter方法名

(3)BeanUtils类用于设置属性,其中包含级联属性实例化

具体过程已记录在代码注释中。

importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.text.SimpleDateFormat;importjava.util.Date;public classClassInstanceFactory{privateClassInstanceFactory(){}/*** 1.首先进行实例化;2.再对实例化对象设置属性值,格式“属性:值|属性:值”

*@paramclazz Class反射实例化

*@paramvalue 为实例化对象设置属性值

*@param

*@return

*/

public static T createInstane(Classclazz, String value){try{

Object obj= clazz.getDeclaredConstructor().newInstance();

BeanUtils.setValue(obj, value);return(T)obj;

}catch(Exception e){return null;

}

}

}classStringUtils{/*** 首字母大写,以获取setter和getter方法

*@paramstr

*@return

*/

public staticString initCap(String str){if(null == str || "".equals(str)){returnstr;

}if(str.length() == 1){returnstr.toUpperCase();

}else{return str.substring(0,1).toUpperCase()+str.substring(1);

}

}

}//为实例化对象设置属性值

classBeanUtils{public static voidsetValue(Object obj, String value){

String[] attrs= value.split("\\|");for(int i = 0; i < attrs.length; i++){

String[] attr= attrs[i].split("\\:");//判断是否是处理级联引用

if(attr[0].contains(".")) {

String[] str= attr[0].split("\\.");try{//1.获取级联属性是否为null

Method getMethod = obj.getClass().getDeclaredMethod("get" + StringUtils.initCap(str[0]));

Object tmp=getMethod.invoke(obj);if(tmp == null){//2.为null时,需要初始化后,再设置属性值//2.1 首先实例化

Field field = obj.getClass().getDeclaredField(str[0]);

tmp= field.getType().getDeclaredConstructor().newInstance();//2.2 设置级联引用的属性

setValue(tmp, attrs[i].substring(attrs[i].indexOf(".")+1));//2.3 将实例化完成的级联属性设置到对象中

Method method = obj.getClass().getDeclaredMethod("set" + StringUtils.initCap(str[0]), field.getType());

method.invoke(obj, tmp);

}else{//3.不为空时,直接设置级联引用的属性

setValue(tmp, attrs[i].substring(attrs[i].indexOf(".")+1));

}

}catch(Exception e){

}

}else{//非级联引用

try{//getField返回所有public的属性; getDeclaredField 返回类所有声明的属性

Field field = obj.getClass().getDeclaredField(attr[0]);//getMethod 返回所有public的方法,包含父类 getDeclaredMethod返回所有声明的方法,不包含父类

Method method = obj.getClass().getDeclaredMethod("set" + StringUtils.initCap(attr[0]), field.getType());//获取属性实际值

Object val = convertType(field.getType().getName(), attr[1]);

method.invoke(obj, val);

}catch(Exception e) {

}

}

}

}private staticObject convertType(String type, String value){if(Integer.class.getName().equals(type) || "int".equals(type)) {returnInteger.valueOf(value);

}else if(Double.class.getName().equals(type) || "double".equals(type)){returnDouble.valueOf(value);

}else if(Long.class.getName().equals(type) || "long".equals(type)){returnLong.valueOf(value);

}else if(Date.class.getName().equals(type)){

SimpleDateFormat sdf= null;if(value.matches("\\d{4}-\\d{2}-\\d{2}")){

sdf= new SimpleDateFormat("yyyy-MM-dd");

}else if(value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {

sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

}else{return newDate();

}try{returnsdf.parse(value);

}catch(Exception e){return newDate();

}

}else{returnvalue;

}

}

}

测试:

/*** 对简单对象进行实例化,并给各属性赋值

* 为避免大量setter代码出现,使用反射机制简化初始化过程*/

public classReflectAndSimplObject {public static voidmain(String[] args){

String value= "name:bob|age:80|birth:1990-10-10|dept.name:ssc|dept.company.name:td|dept.company1.name:ry";

Person p= ClassInstanceFactory.createInstane(Person.class, value);

System.out.println(p);

}

}classCompany{

String name;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

@OverridepublicString toString() {return "Company{" +

"name='" + name + '\'' +

'}';

}

}classCompany1 {

String name;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

@OverridepublicString toString() {return "Company1{" +

"name='" + name + '\'' +

'}';

}

}classDept{

String name;longid;

Company company;

Company1 company1;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicCompany getCompany() {returncompany;

}public voidsetCompany(Company company) {this.company =company;

}public longgetId() {returnid;

}public void setId(longid) {this.id =id;

}publicCompany1 getCompany1() {returncompany1;

}public voidsetCompany1(Company1 company1) {this.company1 =company1;

}

@OverridepublicString toString() {return "Dept{" +

"name='" + name + '\'' +

", id=" + id +

", company=" + company +

", company1=" + company1 +

'}';

}

}classPerson{

String name;intage;

Date birth;

Dept dept;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicDate getBirth() {returnbirth;

}public voidsetBirth(Date birth) {this.birth =birth;

}publicDept getDept() {returndept;

}public voidsetDept(Dept dept) {this.dept =dept;

}

@OverridepublicString toString() {return "Person{" +

"name='" + name + '\'' +

", age=" + age +

", birth=" + birth +

", dept=" + dept +

'}';

}

}

输出:

Person{name='bob', age=80, birth=Wed Oct 10 00:00:00 CST 1990, dept=Dept{name='ssc', id=0, company=Company{name='td'}, company1=Company1{name='ry'}}}

总结

反射的使用,将增加代码的灵活性,并使代码编写更简洁。可以将这个作为以后项目的工具,简化diamagnetic编写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值