java如何用反射將一個對象復制給另一個對象
更新時間:2023年09月25日 09:16:29 作者:YoungMirror
這篇文章主要介紹了java如何用反射將一個對象復制給另一個對象問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
java用反射將一個對象復制給另一個對象
@SneakyThrows public static Object objectClone(Object newObject,Object oldObject){ Field[] oldFields = oldObject.getClass().getDeclaredFields(); Field newField; for (Field oldField : oldFields){ oldField.setAccessible(true); newField = newObject.getClass().getDeclaredField(oldField.getName()); newField.setAccessible(true); newField.set(newObject,oldField.get(oldObject)); } return newObject; }
java復制一個對象使新對象和源對象值相同,地址不同
1. 實體(3個 模擬多層父級)支持多層父級和List,map的copy值
public class StudentDemo extends StudentF { private Integer stuId; private String stuName; private String stuPrice; private boolean flg; private List<String> listString; private HashMap<String, StuType> mapType; public HashMap<String, StuType> getMapType() { return mapType; } public void setMapType(HashMap<String, StuType> mapType) { this.mapType = mapType; } public List<String> getListString() { return listString; } public void setListString(List<String> listString) { this.listString = listString; } public boolean isFlg() { return flg; } public void setFlg(boolean flg) { this.flg = flg; } public StudentDemo(HashMap<String, StuType> mapType, List<StuType> listType, List<String> listString, Integer stuId, String stuName, String stuPrice, String stuSex, Integer stuAge, String stuNum, String stuTel, boolean isFlg) { this.stuId = stuId; this.stuName = stuName; this.stuPrice = stuPrice; super.setStudentSex(stuSex); super.setStudentAge(stuAge); super.setStuNum(stuNum); super.setTel(stuTel); this.flg = isFlg; this.listString = listString; super.setListType(listType); this.mapType = mapType; } public StudentDemo(){} @Override public String toString() { return "StudentDemo{" + "stuId=" + stuId + ", stuName='" + stuName + '\'' + ", stuPrice='" + stuPrice + '\'' + ", stuSex='" + super.getStudentSex() + '\'' + ", stuAge='" + super.getStudentAge() + '\'' + ", stuNum='" + super.getStuNum() + '\'' + ", stuTel='" + super.getTel() + '\'' + ", flg='" + flg + '\'' + ", listString='" + listString + '\'' + ", listType='" + super.getListType() + '\'' + ", mapType='" + mapType + '\'' + '}'; } public Integer getStuId() { return stuId; } public void setStuId(Integer stuId) { this.stuId = stuId; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getStuPrice() { return stuPrice; } public void setStuPrice(String stuPrice) { this.stuPrice = stuPrice; } } public class StudentF extends StudentX { private String studentSex; private Integer studentAge; private List<StuType> listType; public List<StuType> getListType() { return listType; } public void setListType(List<StuType> listType) { this.listType = listType; } public String getStudentSex() { return studentSex; } public void setStudentSex(String studentSex) { this.studentSex = studentSex; } public Integer getStudentAge() { return studentAge; } public void setStudentAge(Integer studentAge) { this.studentAge = studentAge; } } public class StudentX { private String stuNum; private String Tel; public String getStuNum() { return stuNum; } public void setStuNum(String stuNum) { this.stuNum = stuNum; } public String getTel() { return Tel; } public void setTel(String tel) { Tel = tel; } }
2. 工具類
package com.books.utils; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 復制一個實體對象 * 修改新對象時不影響源對象的值 * @param <T> 項目中任意類型 */ public class CopyObjectEntity<T> { /** * 復制實體方法 * @param orderEntity 源對象 * @param newEntity 新對象 * @return 新對象 */ public T newPojo(Object orderEntity, Object newEntity){ // 新對象 T newPojo = null; try { // 源對象 T orderPojo = (T)orderEntity; newPojo = (T)newEntity; // 獲取所有方法,包括父類 Method[] orderObject = orderPojo.getClass().getMethods(); // 遍歷所有方法 for(int a = 0; a < orderObject.length; a ++){ // 得到每一個方法名稱 String name = orderObject[a].getName(); // 判斷獲取需要的(普通的字段都是get/set),這里獲取get方法因為get到值才能賦值 if(!name.equals("setClass") && !name.equals("class") && !name.equals("getClass") && name.startsWith("get")){ // 獲取方法 Method method = orderPojo.getClass().getMethod(name, new Class[] {}); // 執(zhí)行方法 Object value = method.invoke(orderPojo, new Object[] {}); // 拼接set方法 String aa = orderObject[a].getName().substring(3); String bb = aa.substring(0, 1).toUpperCase(); String setter = bb + aa.substring(1); // 創(chuàng)建描述器 PropertyDescriptor pd = new PropertyDescriptor(setter, newPojo.getClass()); //為上面聲明的字段設置set方法(又稱內省) Method setMethod = pd.getWriteMethod(); // 執(zhí)行set setMethod.invoke(newPojo, value); } // 判斷是boolean的字段get時為is if(!name.equals("setClass") && !name.equals("class") && !name.equals("getClass") && name.startsWith("is")){ Method method = orderPojo.getClass().getMethod(name, new Class[] {}); Object value = method.invoke(orderPojo, new Object[] {}); String aa = orderObject[a].getName().substring(2); String bb = aa.substring(0, 1).toUpperCase(); String setter = bb + aa.substring(1); PropertyDescriptor pd = new PropertyDescriptor(setter, newPojo.getClass()); //為上面聲明的字段設置set方法(又稱內?。? Method setMethod = pd.getWriteMethod(); // 執(zhí)行set setMethod.invoke(newPojo, value); } } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IntrospectionException e) { e.printStackTrace(); }catch (Exception e) { e.printStackTrace(); } return newPojo; } }
3. 測試
public void test7(){ List<String> ls = new ArrayList<>(); ls.add("aa"); ls.add("bb"); ls.add("cc"); List<StuType> listType = new ArrayList<>(); listType.add(new StuType(1, "類型1")); listType.add(new StuType(2, "類型2")); HashMap<String, StuType> mapType = new HashMap<>(); mapType.put("11", new StuType(11, "map1")); mapType.put("22", new StuType(22, "map2")); StudentDemo studentDemo = new StudentDemo(mapType, listType, ls,1, "aa" ,null, "男", 23, "010010", "15244669988", true); StudentDemo studentDemo1 = new StudentDemo(); new CopyObjectEntity<StudentDemo>().newPojo(studentDemo, studentDemo1); System.out.println("復制完的新對象"+studentDemo1); studentDemo1.setStuId(22); studentDemo1.setStuName("你好啊"); studentDemo1.setStuPrice("啦啦啦"); studentDemo1.setStudentSex("女"); studentDemo1.setStudentAge(20); studentDemo1.setStuNum("沒有學號"); studentDemo1.setTel("沒有電話"); studentDemo1.setFlg(false); List<String> ls1 = new ArrayList<>(); ls1.add("33"); ls1.add("44"); ls1.add("55"); List<StuType> listType1 = new ArrayList<>(); listType1.add(new StuType(-1, "類型-1")); listType1.add(new StuType(-2, "類型-2")); HashMap<String, StuType> mapType1 = new HashMap<>(); mapType1.put("11", new StuType(-11, "map-1")); mapType1.put("22", new StuType(-22, "map-2")); studentDemo1.setListType(listType1); studentDemo1.setMapType(mapType1); studentDemo1.setListString(ls1); System.out.println("源對象"+studentDemo); System.out.println("修改復制后對象"+studentDemo1); System.out.println("再次查看源對象"+studentDemo); }
4. 結果
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java超詳細教你寫一個斗地主洗牌發(fā)牌系統(tǒng)
這篇文章主要介紹了怎么用Java來你寫一個斗地主種洗牌和發(fā)牌的功能,斗地主相信大家都知道,同時也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來實現這個功能,感興趣的朋友跟隨文章往下看看吧2022-03-03SpringBoot整合RocketMQ實現發(fā)送同步消息
RocketMQ 是一款開源的分布式消息中間件,由阿里巴巴開源,它具有高可用性、高性能、低延遲等特點,廣泛應用于阿里巴巴集團內部以及眾多外部企業(yè)的業(yè)務系統(tǒng)中,本文給大家介紹了SpringBoot整合RocketMQ實現發(fā)送同步消息,需要的朋友可以參考下2024-04-04MyBatis中的XML實現和動態(tài)SQL實現示例詳解
這篇文章主要介紹了MyBatis中的XML實現和動態(tài)SQL實現,我們可以將XML中重復出現的內容提取出來放到sql標簽中,當需要用到sql標簽中的內容時,用include標簽將sql標簽中的內容引進來即可,感興趣的朋友跟隨小編一起看看吧2024-02-02