一.傳統簡單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操做來完成,而這種形式,是在正規開發之中廣泛採用的方式