java反射(四)--反射与简单java类

一.传统简单java类
  简单的java类主要是由属性所组成,而且提供有相应的setter以及getter的处理方法,同时简单java类最大的特征就是经过对象保存相应的类的属性内容,可是若是使用传统的简单java类的开发,那么也会面临很是麻烦的困难:
java

 1 class Emp{  2 private String ename;  3 private String job;  4  5 public void setEname(String ename) {  6 this.ename = ename;  7  }  8  9 public void setJob(String job) { 10 this.job = job; 11  } 12 13 public String getEname() { 14 return ename; 15  } 16 17 public String getJob() { 18 return job; 19  } 20 }

--按照传统的作法,首先应该实例化Emp对象,然后经过实例化对象进行setter方法的调用来设置属性的内容:编程

 1 class Emp{  2 private String ename;  3 private String job;  4  5 public void setEname(String ename) {  6 this.ename = ename;  7  }  8  9 public void setJob(String job) { 10 this.job = job; 11  } 12 13 public String getEname() { 14 return ename; 15  } 16 17 public String getJob() { 18 return job; 19  } 20 } 21 public class ReflectAndJavaClassDemo { 22 public static void main(String[] args) { 23 Emp emp = new Emp(); 24 emp.setEname("Mike"); 25 emp.setJob("code java"); 26 System.out.println("姓名: " + emp.getEname() + " 职位: " + emp.getJob()); 27  } 28 }

--在整个进行Emp对象实例化并设置数据的操做过程之中,设置数据的部分是为麻烦的,能够想象若是如今Emp类中提供有50个属性,那么对于整个程序而言,将成为一大堆的setter方法的调用,即便使用构造方法赋值,也会形成不少的麻烦.或者我们再进一步说明,在一个开发之中,简单java类的个数是很是多的,那么若是全部的简单java类都牵扯到属性赋值的问题时,咱们代码的重复率会很是的高.按照传统直观的编程方式所带来的问题就是代码会存在大量的重复操做,若是要想解决对象的重复处理操做,那么惟一的解决方案就是反射机制,反射机制最大的特征就是能够根据其自身的特色(Object类直接操做属性和方法,实现相同功能类的重复操做的抽象处理).数组

二.属性自动设置解决方案:
  通过了分析以后已经确认了当前简单java类操做的问题所在,而对于开发者而言就须要想办法经过一种解决方案来实现属性内容的自动设置,那么这个时候的设置强烈建议采用字符串的形式来描述对应的类型:
--1.在进行程序开发的时候咱们能够知道String字符串能够描述的类型由不少,而且也能够由开发者自行定义String字符串的结构,咱们采用"内容|属性:内容|"的形式来为简单java类中的属性进行初始化;
--2.类设计的基本结构,应该由一个专门的工具类(ClassInstanceFactory类)负责全部的反射处理,即接收反射对象,同时能够获取指定类的实例化对象;
--3.设计的基本结构
ide

 1 package 反射.反射与java类;  2  3 /**  4  * @author : S K Y  5  * @version :0.0.1  6 */  7 class Emp {  8 private String ename;  9 private String job; 10 11 public void setEname(String ename) { 12 this.ename = ename; 13  } 14 15 public void setJob(String job) { 16 this.job = job; 17  } 18 19 public String getEname() { 20 return ename; 21  } 22 23 public String getJob() { 24 return job; 25  } 26 } 27 28 class ClassInstanceFactory { 29 private ClassInstanceFactory() { 30 } //构造方法私有化 31 32 /** 33  * 实例化对象建立的方法,该对象能够根据传入的字符串的结构"内容|属性:内容|"进行处理 34  * 35  * @param tClass 要进行反射实例化的Class类对象,有Class就能够反射实例化对象 36  * @param value 要设置给对象的属性内容 37  * @return 一个已经配置完内容的简单java类对象 38 */ 39 public static <T> T create(Class<T> tClass, String value) { 40 return null; 41  } 42 43 } 44 45 public class ReflectAndJavaClassDemo { 46 public static void main(String[] args) { 47 //在Emp类中,存在两个String类型的成员变量ename,job,以及其相关的getter,setter 48 String value = "ename:Mike|job:code java"; 49 Emp emp = ClassInstanceFactory.create(Emp.class, value); //产生实例化对象 50  } 51 }

--这样在当前的开发之中,所须要留给用户完善的就是ClassInstanceFactory.create()方法的具体实现工具

三.单级属性配置
  对于此时的Emp类型里面会发现所给出的数据类型都没有其余的引用关联了,只是描述了Emp本类的对象,这样的设置咱们称他为单级属性配置,因此此时应该须要处理两件事情:
--1.须要经过反射进行指定类对象的实例化处理;
--2.进行内容的设置(Field属性类型,方法名称,要设置的内容)
this

 1 package 反射.反射与java类;  2  3 import java.lang.reflect.Field;  4 import java.lang.reflect.Method;  5  6 /**  7  * @author : S K Y  8  * @version :0.0.1  9 */  10 class Emp {  11 private String ename;  12 private String job;  13  14 public void setEname(String ename) {  15 this.ename = ename;  16  }  17  18 public void setJob(String job) {  19 this.job = job;  20  }  21  22 public String getEname() {  23 return ename;  24  }  25  26 public String getJob() {  27 return job;  28  }  29 }  30  31 class ClassInstanceFactory {  32 private ClassInstanceFactory() {  33 } //构造方法私有化  34  35 /**  36  * 实例化对象建立的方法,该对象能够根据传入的字符串的结构"内容|属性:内容|"进行处理  37  *  38  * @param tClass 要进行反射实例化的Class类对象,有Class就能够反射实例化对象  39  * @param value 要设置给对象的属性内容  40  * @return 一个已经配置完内容的简单java类对象  41 */  42 public static <T> T create(Class<T> tClass, String value) {  43 //若是想采用反射进行简单Java类对象的属性设置的时候,类中必需要有无参构造  44 try {  45 Object o = tClass.newInstance();  46 BeanUtils.setValue(o, value); //经过反射设置属性  47 return tClass.cast(o); //获取对象  48 } catch (Exception e) {  49 e.printStackTrace(); //此时若是出现异常,将异常抛出也没有多大做用  50 return null;  51  }  52  53  54  }  55  56 }  57  58 class BeanUtils { //进行Bean处理的工具类  59 private BeanUtils() {  60  }  61  62 /**  63  * 实现指定对象的属性设置  64  *  65  * @param obj 要进行反射操做的实例化对象  66  * @param value 包含有指定内容的字符串  67 */  68 public static void setValue(Object obj, String value) {  69 String results[] = value.split("\\|");//按照竖线进行每一组属性的拆分  70 for (int i = 0; i < results.length; i++) { //循环设置属性内容  71 String attval[] = results[i].split(":"); //获取属性名称及内容  72 try {  73 Field field = obj.getClass().getDeclaredField(attval[0]);  74 Method setMethod = obj.getClass()  75 .getDeclaredMethod("set" + StringUtils.initcap(attval[0]), field.getType());  76 setMethod.invoke(obj,attval[1]); //使用setter方法进行内容的赋值  77 } catch (Exception e) { //捕获异常,不然的话一个属性不存在将会致使全部的属性都没法正常赋值  78  }  79  80  }  81  }  82 }  83  84 class StringUtils {  85 private StringUtils() {  86  }  87  88 public static String initcap(String str) {  89 if (str == null || str.equals("")) {  90 return str;  91  }  92 if (str.length() == 1) {  93 return str.toUpperCase();  94 } else {  95 return str.substring(0, 1).toUpperCase() + str.substring(1);  96  }  97  }  98  99 } 100 101 public class ReflectAndJavaClassDemo { 102 public static void main(String[] args) { 103 //在Emp类中,存在两个String类型的成员变量ename,job,以及其相关的getter,setter 104 String value = "ename:Mike|job:code java"; 105 Emp emp = ClassInstanceFactory.create(Emp.class, value); //产生实例化对象 106 System.out.println("姓名: " + emp.getEname() + " 职位: " + emp.getJob()); 107  } 108 }

--运行结果spa

姓名: Mike 职位: code java Process finished with exit code 0

--ClassInstanceFactory负责实例化对象而且调用BeanUtils类实现属性代码的设置,此时即使类中的属性再多,那么也能够轻松的实现setter的调用,轻松实现类对象实例化处理设计

四.设置多种数据类型
  虽然上述代码能够实现对于属性的配置,可是咱们仍然须要考虑一个实际的状况,当前所给定的数据类型只能是String,可是在实际的开发之中,面对简单java类中的属性类型通常的可选为:Long(long),Integer(int),Double(double),String,Date(日期,日期时间),因此这个时候对于当前的程序代码就必须作出修改,要求能够实现各类数据类型的配置.
--既然要求能够实现不一样类型的内容设置,而且BeanUtils类主要是完成属性赋值处理的,那么就能够在这个类之中追加有一些列的处理方法:
code

 1 package 反射.反射与java类;  2  3 import java.lang.reflect.Field;  4 import java.lang.reflect.Method;  5 import java.text.ParseException;  6 import java.text.SimpleDateFormat;  7 import java.util.Date;  8  9 /**  10  * @author : S K Y  11  * @version :0.0.1  12 */  13 class Emp {  14 private long empo;  15 private String ename;  16 private String job;  17 private double salary;  18 private Date hireDate;  19  20 public void setEname(String ename) {  21 this.ename = ename;  22  }  23  24 public void setJob(String job) {  25 this.job = job;  26  }  27  28 public String getEname() {  29 return ename;  30  }  31  32 public String getJob() {  33 return job;  34  }  35  36 public long getEmpo() {  37 return empo;  38  }  39  40 public void setEmpo(long empo) {  41 this.empo = empo;  42  }  43  44 public double getSalary() {  45 return salary;  46  }  47  48 public void setSalary(double salary) {  49 this.salary = salary;  50  }  51  52 public Date getHireDate() {  53 return hireDate;  54  }  55  56 public void setHireDate(Date hireDate) {  57 this.hireDate = hireDate;  58  }  59  60  @Override  61 public String toString() {  62 return "Emp{" +  63 "empo=" + empo +  64 ", ename='" + ename + '\'' +  65 ", job='" + job + '\'' +  66 ", salary=" + salary +  67 ", hireDate=" + hireDate +  68 '}';  69  }  70 }  71  72 class ClassInstanceFactory {  73 private ClassInstanceFactory() {  74 } //构造方法私有化  75  76 /**  77  * 实例化对象建立的方法,该对象能够根据传入的字符串的结构"内容|属性:内容|"进行处理  78  *  79  * @param tClass 要进行反射实例化的Class类对象,有Class就能够反射实例化对象  80  * @param value 要设置给对象的属性内容  81  * @return 一个已经配置完内容的简单java类对象  82 */  83 public static <T> T create(Class<T> tClass, String value) {  84 //若是想采用反射进行简单Java类对象的属性设置的时候,类中必需要有无参构造  85 try {  86 Object o = tClass.newInstance();  87 BeanUtils.setValue(o, value); //经过反射设置属性  88 return tClass.cast(o); //获取对象  89 } catch (Exception e) {  90 e.printStackTrace(); //此时若是出现异常,将异常抛出也没有多大做用  91 return null;  92  }  93  94  95  }  96  97 }  98  99 class BeanUtils { //进行Bean处理的工具类 100 private BeanUtils() { 101  } 102 103 /** 104  * 实现指定对象的属性设置 105  * 106  * @param obj 要进行反射操做的实例化对象 107  * @param value 包含有指定内容的字符串 108 */ 109 public static void setValue(Object obj, String value) { 110 String results[] = value.split("\\|");//按照竖线进行每一组属性的拆分 111 for (int i = 0; i < results.length; i++) { //循环设置属性内容 112 String attval[] = results[i].split(":"); //获取属性名称及内容 113 try { 114 Field field = obj.getClass().getDeclaredField(attval[0]); 115 Method setMethod = obj.getClass() 116 .getDeclaredMethod("set" + StringUtils.initcap(attval[0]), field.getType()); 117 Object val = BeanUtils.getAttributeValue(field.getType().getName(), attval[1]); 118 setMethod.invoke(obj, val); //使用setter方法进行内容的赋值 119 } catch (Exception e) { //捕获异常,不然的话一个属性不存在将会致使全部的属性都没法正常赋值 120  } 121 122  } 123  } 124 125 /** 126  * 实现属性类型转化处理 127  * 128  * @param type 属性类型,经过Field获取 129  * @param value 属性的内容,传入的都是字符串,须要将其转化为指定的类型 130  * @return 转化后的数据 131 */ 132 private static Object getAttributeValue(String type, String value) { 133 if ("long".equals(type) || "java.lang.Long".equals(type)) { //长整型 134 return Long.parseLong(value); 135 } else if ("int".equals(type) || "java.lang.Integer".equals(type)) { 136 return Integer.valueOf(value); 137 } else if ("double".equals(type) || "java.lang.Double".equals(type)) { 138 return Double.valueOf(value); 139 } else if ("java.util.Date".equals(type)) { 140 SimpleDateFormat dateFormat = null; 141 if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { //日期类型 142 dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 143 } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) { //日期时间 144 dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 145 } else { 146 return new Date(); //当前日期 147  } 148 try { 149 return dateFormat.parse(value); 150 } catch (ParseException e) { 151 return new Date(); 152  } 153 } else { 154 return value; 155  } 156  } 157 } 158 159 class StringUtils { 160 private StringUtils() { 161  } 162 163 public static String initcap(String str) { 164 if (str == null || str.equals("")) { 165 return str; 166  } 167 if (str.length() == 1) { 168 return str.toUpperCase(); 169 } else { 170 return str.substring(0, 1).toUpperCase() + str.substring(1); 171  } 172  } 173 174 } 175 176 public class ReflectAndJavaClassDemo { 177 public static void main(String[] args) { 178 //在Emp类中,存在两个String类型的成员变量ename,job,以及其相关的getter,setter 179 String value = "ename:Mike|job:code java|empo:1258|salary:750|hireDate:1911-12-12"; 180 Emp emp = ClassInstanceFactory.create(Emp.class, value); //产生实例化对象 181  System.out.println(emp); 182  } 183 }

--运行结果orm

Emp{empo=1258, ename='Mike', job='code java', salary=750.0, hireDate=Tue Dec 12 00:00:00 CST 1911} Process finished with exit code 0

--此时只是列举出了经常使用的几种数据类型,固然若是想将其做为一个产品推广,那就必需要考虑全部可能出现的数据类型,同时可能出现的日期格式也须要考虑

五.级联对象实例化
  若是说如今给定的类对象之中存在有其余的引用的级联关系的状况下,成为多级设置,例如:一个雇员属于一个部门,一个部门属于一个公司,因此这个时候对于简单Java类的定义以下:

 1 class Company {  2 private String name;  3 private Date createDate;  4  5 public String getName() {  6 return name;  7  }  8  9 public void setName(String name) {  10 this.name = name;  11  }  12  13 public Date getCreateDate() {  14 return createDate;  15  }  16  17 public void setCreateDate(Date createDate) {  18 this.createDate = createDate;  19  }  20 }  21  22 class Dept {  23 private String dname;  24 private String loc;  25 private Company company;  26  27 public String getDname() {  28 return dname;  29  }  30  31 public void setDname(String dname) {  32 this.dname = dname;  33  }  34  35 public String getLoc() {  36 return loc;  37  }  38  39 public void setLoc(String loc) {  40 this.loc = loc;  41  }  42  43 public Company getCompany() {  44 return company;  45  }  46  47 public void setCompany(Company company) {  48 this.company = company;  49  }  50 }  51  52 class Emp {  53 private long empo;  54 private String ename;  55 private String job;  56 private double salary;  57 private Date hireDate;  58 private Dept dept;  59  60 public Dept getDept() {  61 return dept;  62  }  63  64 public void setDept(Dept dept) {  65 this.dept = dept;  66  }  67  68 public void setEname(String ename) {  69 this.ename = ename;  70  }  71  72 public void setJob(String job) {  73 this.job = job;  74  }  75  76 public String getEname() {  77 return ename;  78  }  79  80 public String getJob() {  81 return job;  82  }  83  84 public long getEmpo() {  85 return empo;  86  }  87  88 public void setEmpo(long empo) {  89 this.empo = empo;  90  }  91  92 public double getSalary() {  93 return salary;  94  }  95  96 public void setSalary(double salary) {  97 this.salary = salary;  98  }  99 100 public Date getHireDate() { 101 return hireDate; 102  } 103 104 public void setHireDate(Date hireDate) { 105 this.hireDate = hireDate; 106  } 107 108  @Override 109 public String toString() { 110 return "Emp{" + 111 "empo=" + empo + 112 ", ename='" + ename + '\'' + 113 ", job='" + job + '\'' + 114 ", salary=" + salary + 115 ", hireDate=" + hireDate + 116 '}'; 117  } 118 }

--若是要经过Emp进行操做,则应该按照使用"."做为级联关系的处理,例: dept.dname,dept.loc,company.name,company.createDate
  dept.dname:财务部  Emp类实例对象.getDept().setDname("财务部");
--考虑能够经过级联的配置,实现类中属性的实例化: String value ="ename:Mike|job:code java|empo:1258|salary:750|hireDate:1911-12-12|dept.dname:财务部" +"|dept.company.name:一个写java的公司";如今的属性存在多级关系,那么对于多级的关系就必须与单级的配置区分开

 1 package 反射.反射与java类;  2  3 import java.lang.reflect.Field;  4 import java.lang.reflect.Method;  5 import java.text.ParseException;  6 import java.text.SimpleDateFormat;  7 import java.util.Arrays;  8 import java.util.Date;  9  10 /**  11  * @author : S K Y  12  * @version :0.0.1  13 */  14 class Company {  15 private String name;  16 private Date createDate;  17  18 public String getName() {  19 return name;  20  }  21  22 public void setName(String name) {  23 this.name = name;  24  }  25  26 public Date getCreateDate() {  27 return createDate;  28  }  29  30 public void setCreateDate(Date createDate) {  31 this.createDate = createDate;  32  }  33 }  34  35 class Dept {  36 private String dname;  37 private String loc;  38 private Company company;  39  40 public String getDname() {  41 return dname;  42  }  43  44 public void setDname(String dname) {  45 this.dname = dname;  46  }  47  48 public String getLoc() {  49 return loc;  50  }  51  52 public void setLoc(String loc) {  53 this.loc = loc;  54  }  55  56 public Company getCompany() {  57 return company;  58  }  59  60 public void setCompany(Company company) {  61 this.company = company;  62  }  63 }  64  65 class Emp {  66 private long empo;  67 private String ename;  68 private String job;  69 private double salary;  70 private Date hireDate;  71 private Dept dept;  72  73 public Dept getDept() {  74 return dept;  75  }  76  77 public void setDept(Dept dept) {  78 this.dept = dept;  79  }  80  81 public void setEname(String ename) {  82 this.ename = ename;  83  }  84  85 public void setJob(String job) {  86 this.job = job;  87  }  88  89 public String getEname() {  90 return ename;  91  }  92  93 public String getJob() {  94 return job;  95  }  96  97 public long getEmpo() {  98 return empo;  99  } 100 101 public void setEmpo(long empo) { 102 this.empo = empo; 103  } 104 105 public double getSalary() { 106 return salary; 107  } 108 109 public void setSalary(double salary) { 110 this.salary = salary; 111  } 112 113 public Date getHireDate() { 114 return hireDate; 115  } 116 117 public void setHireDate(Date hireDate) { 118 this.hireDate = hireDate; 119  } 120 121  @Override 122 public String toString() { 123 return "Emp{" + 124 "empo=" + empo + 125 ", ename='" + ename + '\'' + 126 ", job='" + job + '\'' + 127 ", salary=" + salary + 128 ", hireDate=" + hireDate + 129 '}'; 130  } 131 } 132 133 class ClassInstanceFactory { 134 private ClassInstanceFactory() { 135 } //构造方法私有化 136 137 /** 138  * 实例化对象建立的方法,该对象能够根据传入的字符串的结构"内容|属性:内容|"进行处理 139  * 140  * @param tClass 要进行反射实例化的Class类对象,有Class就能够反射实例化对象 141  * @param value 要设置给对象的属性内容 142  * @return 一个已经配置完内容的简单java类对象 143 */ 144 public static <T> T create(Class<T> tClass, String value) { 145 //若是想采用反射进行简单Java类对象的属性设置的时候,类中必需要有无参构造 146 try { 147 Object o = tClass.newInstance(); 148 BeanUtils.setValue(o, value); //经过反射设置属性 149 return tClass.cast(o); //获取对象 150 } catch (Exception e) { 151 e.printStackTrace(); //此时若是出现异常,将异常抛出也没有多大做用 152 return null; 153  } 154 155 156  } 157 158 } 159 160 class BeanUtils { //进行Bean处理的工具类 161 private BeanUtils() { 162  } 163 164 /** 165  * 实现指定对象的属性设置 166  * 167  * @param obj 要进行反射操做的实例化对象 168  * @param value 包含有指定内容的字符串 169 */ 170 public static void setValue(Object obj, String value) { 171 String results[] = value.split("\\|");//按照竖线进行每一组属性的拆分 172 for (int i = 0; i < results.length; i++) { //循环设置属性内容 173 String attval[] = results[i].split(":"); //获取属性名称及内容 174 try { 175 Object currentObject = obj; 176 if (attval[0].contains(".")) { //这是多级配置 177 String temp[] = attval[0].split("\\."); 178 //最后一位确定是指定类中的属性名称,所以不在实例化处理的范畴以内 179 for (int j = 0; j < temp.length - 1; j++) { //实例化 180 //调用相应的getter方法,若是getter方法返回了空表示该对象为实例化 181 Method getMethod = currentObject.getClass().getDeclaredMethod( 182 "get" + StringUtils.initcap(temp[j])); 183 if (getMethod.invoke(currentObject) == null) { //该对象如今并无被实例化 184 Field field = currentObject.getClass().getDeclaredField(temp[j]); 185 Method method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[j]), field.getType()); 186 Object newObject = field.getType().getDeclaredConstructor().newInstance(); 187  method.invoke(currentObject, newObject); 188 currentObject = newObject; 189 } else { 190 currentObject = getMethod.invoke(currentObject); 191  } 192  } 193 } else { 194 Field field = obj.getClass().getDeclaredField(attval[0]); 195 Method setMethod = obj.getClass() 196 .getDeclaredMethod("set" + StringUtils.initcap(attval[0]), field.getType()); 197 Object val = BeanUtils.getAttributeValue(field.getType().getName(), attval[1]); 198 setMethod.invoke(obj, val); //使用setter方法进行内容的赋值 199  } 200 } catch (Exception e) { //捕获异常,不然的话一个属性不存在将会致使全部的属性都没法正常赋值 201  } 202 203  } 204  } 205 206 /** 207  * 实现属性类型转化处理 208  * 209  * @param type 属性类型,经过Field获取 210  * @param value 属性的内容,传入的都是字符串,须要将其转化为指定的类型 211  * @return 转化后的数据 212 */ 213 private static Object getAttributeValue(String type, String value) { 214 if ("long".equals(type) || "java.lang.Long".equals(type)) { //长整型 215 return Long.parseLong(value); 216 } else if ("int".equals(type) || "java.lang.Integer".equals(type)) { 217 return Integer.valueOf(value); 218 } else if ("double".equals(type) || "java.lang.Double".equals(type)) { 219 return Double.valueOf(value); 220 } else if ("java.util.Date".equals(type)) { 221 SimpleDateFormat dateFormat = null; 222 if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { //日期类型 223 dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 224 } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) { //日期时间 225 dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 226 } else { 227 return new Date(); //当前日期 228  } 229 try { 230 return dateFormat.parse(value); 231 } catch (ParseException e) { 232 return new Date(); 233  } 234 } else { 235 return value; 236  } 237  } 238 } 239 240 class StringUtils { 241 private StringUtils() { 242  } 243 244 public static String initcap(String str) { 245 if (str == null || str.equals("")) { 246 return str; 247  } 248 if (str.length() == 1) { 249 return str.toUpperCase(); 250 } else { 251 return str.substring(0, 1).toUpperCase() + str.substring(1); 252  } 253  } 254 255 } 256 257 public class ReflectAndJavaClassDemo { 258 public static void main(String[] args) { 259 //在Emp类中,存在两个String类型的成员变量ename,job,以及其相关的getter,setter 260 String value = 261 "ename:Mike|job:code java|empo:1258|salary:750|hireDate:1911-12-12|dept.dname:财务部" + 262 "|dept.company.name:一个写java的公司"; 263 Emp emp = ClassInstanceFactory.create(Emp.class, value); //产生实例化对象 264  System.out.println(emp.getDept().getCompany()); 265  } 266 }

--运行结果

反射.反射与java类.Company@610455d6 Process finished with exit code 0

--这些自动的级联配置的实例化处理操做,在进行项目的编写之中将有很大的用处

六.级联属性设置
  如今已经成功实现级联对象的实例化处理,那么咱们应该考虑级联的属性设置了.在以前考虑级联对象实例化处理的时候,循环进行实例化处理时数组的最后一位是没有被进行实例化的,由于数组的最后一位就是咱们要操做的成员,按照以前的方式利用对象进行setter方法的调用:

 1 package 反射.反射与java类;  2  3 import java.lang.reflect.Field;  4 import java.lang.reflect.Method;  5 import java.text.ParseException;  6 import java.text.SimpleDateFormat;  7 import java.util.Date;  8  9 /**  10  * @author : S K Y  11  * @version :0.0.1  12 */  13 class Company {  14 private String name;  15 private Date createDate;  16  17 public String getName() {  18 return name;  19  }  20  21 public void setName(String name) {  22 this.name = name;  23  }  24  25 public Date getCreateDate() {  26 return createDate;  27  }  28  29 public void setCreateDate(Date createDate) {  30 this.createDate = createDate;  31  }  32  33  @Override  34 public String toString() {  35 return "Company{" +  36 "name='" + name + '\'' +  37 ", createDate=" + createDate +  38 '}';  39  }  40 }  41  42 class Dept {  43 private String dname;  44 private String loc;  45 private Company company;  46  47 public String getDname() {  48 return dname;  49  }  50  51 public void setDname(String dname) {  52 this.dname = dname;  53  }  54  55 public String getLoc() {  56 return loc;  57  }  58  59 public void setLoc(String loc) {  60 this.loc = loc;  61  }  62  63 public Company getCompany() {  64 return company;  65  }  66  67 public void setCompany(Company company) {  68 this.company = company;  69  }  70  71  @Override  72 public String toString() {  73 return "Dept{" +  74 "dname='" + dname + '\'' +  75 ", loc='" + loc + '\'' +  76 ", company=" + company +  77 '}';  78  }  79 }  80  81 class Emp {  82 private long empo;  83 private String ename;  84 private String job;  85 private double salary;  86 private Date hireDate;  87 private Dept dept;  88  89 public Dept getDept() {  90 return dept;  91  }  92  93 public void setDept(Dept dept) {  94 this.dept = dept;  95  }  96  97 public void setEname(String ename) {  98 this.ename = ename;  99  } 100 101 public void setJob(String job) { 102 this.job = job; 103  } 104 105 public String getEname() { 106 return ename; 107  } 108 109 public String getJob() { 110 return job; 111  } 112 113 public long getEmpo() { 114 return empo; 115  } 116 117 public void setEmpo(long empo) { 118 this.empo = empo; 119  } 120 121 public double getSalary() { 122 return salary; 123  } 124 125 public void setSalary(double salary) { 126 this.salary = salary; 127  } 128 129 public Date getHireDate() { 130 return hireDate; 131  } 132 133 public void setHireDate(Date hireDate) { 134 this.hireDate = hireDate; 135  } 136 137  @Override 138 public String toString() { 139 return "Emp{" + 140 "empo=" + empo + 141 ", ename='" + ename + '\'' + 142 ", job='" + job + '\'' + 143 ", salary=" + salary + 144 ", hireDate=" + hireDate + 145 ", dept=" + dept + 146 '}'; 147  } 148 } 149 150 class ClassInstanceFactory { 151 private ClassInstanceFactory() { 152 } //构造方法私有化 153 154 /** 155  * 实例化对象建立的方法,该对象能够根据传入的字符串的结构"内容|属性:内容|"进行处理 156  * 157  * @param tClass 要进行反射实例化的Class类对象,有Class就能够反射实例化对象 158  * @param value 要设置给对象的属性内容 159  * @return 一个已经配置完内容的简单java类对象 160 */ 161 public static <T> T create(Class<T> tClass, String value) { 162 //若是想采用反射进行简单Java类对象的属性设置的时候,类中必需要有无参构造 163 try { 164 Object o = tClass.newInstance(); 165 BeanUtils.setValue(o, value); //经过反射设置属性 166 return tClass.cast(o); //获取对象 167 } catch (Exception e) { 168 e.printStackTrace(); //此时若是出现异常,将异常抛出也没有多大做用 169 return null; 170  } 171 172 173  } 174 175 } 176 177 class BeanUtils { //进行Bean处理的工具类 178 private BeanUtils() { 179  } 180 181 /** 182  * 实现指定对象的属性设置 183  * 184  * @param obj 要进行反射操做的实例化对象 185  * @param value 包含有指定内容的字符串 186 */ 187 public static void setValue(Object obj, String value) { 188 String results[] = value.split("\\|");//按照竖线进行每一组属性的拆分 189 for (int i = 0; i < results.length; i++) { //循环设置属性内容 190 String attval[] = results[i].split(":"); //获取属性名称及内容 191 try { 192 Object currentObject = obj; 193 if (attval[0].contains(".")) { //这是多级配置 194 String temp[] = attval[0].split("\\."); 195 //最后一位确定是指定类中的属性名称,所以不在实例化处理的范畴以内 196 for (int j = 0; j < temp.length - 1; j++) { //实例化 197 //调用相应的getter方法,若是getter方法返回了空表示该对象为实例化 198 Method getMethod = currentObject.getClass().getDeclaredMethod( 199 "get" + StringUtils.initcap(temp[j])); 200 if (getMethod.invoke(currentObject) == null) { //该对象如今并无被实例化 201 Field field = currentObject.getClass().getDeclaredField(temp[j]); 202 Method method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[j]), field.getType()); 203 Object newObject = field.getType().getDeclaredConstructor().newInstance(); 204  method.invoke(currentObject, newObject); 205 currentObject = newObject; 206 } else { 207 currentObject = getMethod.invoke(currentObject); 208  } 209  } 210 //进行属性内容的 设置 211 Field field = currentObject.getClass().getDeclaredField(temp[temp.length - 1]); 212 Method setMethod = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[temp.length - 1]), field.getType()); 213 Object val = BeanUtils.getAttributeValue(field.getType().getName(), attval[1]); 214 setMethod.invoke(currentObject, val); //使用setter方法进行内容的赋值 215 } else { 216 Field field = obj.getClass().getDeclaredField(attval[0]); 217 Method setMethod = obj.getClass() 218 .getDeclaredMethod("set" + StringUtils.initcap(attval[0]), field.getType()); 219 Object val = BeanUtils.getAttributeValue(field.getType().getName(), attval[1]); 220 setMethod.invoke(obj, val); //使用setter方法进行内容的赋值 221  } 222 } catch (Exception e) { //捕获异常,不然的话一个属性不存在将会致使全部的属性都没法正常赋值 223  } 224 225  } 226  } 227 228 /** 229  * 实现属性类型转化处理 230  * 231  * @param type 属性类型,经过Field获取 232  * @param value 属性的内容,传入的都是字符串,须要将其转化为指定的类型 233  * @return 转化后的数据 234 */ 235 private static Object getAttributeValue(String type, String value) { 236 if ("long".equals(type) || "java.lang.Long".equals(type)) { //长整型 237 return Long.parseLong(value); 238 } else if ("int".equals(type) || "java.lang.Integer".equals(type)) { 239 return Integer.valueOf(value); 240 } else if ("double".equals(type) || "java.lang.Double".equals(type)) { 241 return Double.valueOf(value); 242 } else if ("java.util.Date".equals(type)) { 243 SimpleDateFormat dateFormat = null; 244 if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { //日期类型 245 dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 246 } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) { //日期时间 247 dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 248 } else { 249 return new Date(); //当前日期 250  } 251 try { 252 return dateFormat.parse(value); 253 } catch (ParseException e) { 254 return new Date(); 255  } 256 } else { 257 return value; 258  } 259  } 260 } 261 262 class StringUtils { 263 private StringUtils() { 264  } 265 266 public static String initcap(String str) { 267 if (str == null || str.equals("")) { 268 return str; 269  } 270 if (str.length() == 1) { 271 return str.toUpperCase(); 272 } else { 273 return str.substring(0, 1).toUpperCase() + str.substring(1); 274  } 275  } 276 277 } 278 279 public class ReflectAndJavaClassDemo { 280 public static void main(String[] args) { 281 //在Emp类中,存在两个String类型的成员变量ename,job,以及其相关的getter,setter 282 String value = 283 "ename:Mike|job:code java|empo:1258|salary:750|hireDate:1911-12-12|dept.dname:财务部" + 284 "|dept.company.name:一个写java的公司"; 285 Emp emp = ClassInstanceFactory.create(Emp.class, value); //产生实例化对象 286  System.out.println(emp); 287  } 288 }

--运行结果

Emp{empo=1258, ename='Mike', job='code java', salary=750.0, hireDate=Tue Dec 12 00:00:00 CST 1911, dept=Dept{dname='财务部', loc='null', company=Company{name='一个写java的公司', createDate=null}}} Process finished with exit code 0

--这样在之后的简单java类的赋值处理将再也不重复调用setter操做来完成,而这种形式,是在正规开发之中广泛采用的方式

相关文章
相关标签/搜索