java反射--反射与简单java类

Posted skykuqi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射--反射与简单java类相关的知识,希望对你有一定的参考价值。

一.传统简单java类
  简单的java类主要是由属性所组成,并且提供有相应的setter以及getter的处理方法,同时简单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.设计的基本结构

 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属性类型,方法名称,要设置的内容)

  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 

--运行结果

姓名: Mike 职位: code java

Process finished with exit code 0

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

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

  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("\\d4-\\d2-\\d2"))  //日期类型
142                 dateFormat = new SimpleDateFormat("yyyy-MM-dd");
143              else if (value.matches("\\d4-\\d2-\\d2 \\d2:\\d2:\\d2"))    //日期时间
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 

--运行结果

Empempo=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("\\d4-\\d2-\\d2"))  //日期类型
223                 dateFormat = new SimpleDateFormat("yyyy-MM-dd");
224              else if (value.matches("\\d4-\\d2-\\d2 \\d2:\\d2:\\d2"))    //日期时间
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("\\d4-\\d2-\\d2"))  //日期类型
245                 dateFormat = new SimpleDateFormat("yyyy-MM-dd");
246              else if (value.matches("\\d4-\\d2-\\d2 \\d2:\\d2:\\d2"))    //日期时间
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 

--运行结果

Empempo=1258, ename=‘Mike‘, job=‘code java‘, salary=750.0, hireDate=Tue Dec 12 00:00:00 CST 1911, dept=Deptdname=‘财务部‘, loc=‘null‘, company=Companyname=‘一个写java的公司‘, createDate=null

Process finished with exit code 0

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

以上是关于java反射--反射与简单java类的主要内容,如果未能解决你的问题,请参考以下文章

:反射与简单java类

Java核心技术梳理-类加载机制与反射

java之反射

Java反射机制

请问java中的反射机制与用法

Java反射与内省