java如何用反射將一個(gè)對(duì)象復(fù)制給另一個(gè)對(duì)象
java用反射將一個(gè)對(duì)象復(fù)制給另一個(gè)對(duì)象
@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復(fù)制一個(gè)對(duì)象使新對(duì)象和源對(duì)象值相同,地址不同
1. 實(shí)體(3個(gè) 模擬多層父級(jí))支持多層父級(jí)和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. 工具類(lèi)
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; /** * 復(fù)制一個(gè)實(shí)體對(duì)象 * 修改新對(duì)象時(shí)不影響源對(duì)象的值 * @param <T> 項(xiàng)目中任意類(lèi)型 */ public class CopyObjectEntity<T> { /** * 復(fù)制實(shí)體方法 * @param orderEntity 源對(duì)象 * @param newEntity 新對(duì)象 * @return 新對(duì)象 */ public T newPojo(Object orderEntity, Object newEntity){ // 新對(duì)象 T newPojo = null; try { // 源對(duì)象 T orderPojo = (T)orderEntity; newPojo = (T)newEntity; // 獲取所有方法,包括父類(lèi) Method[] orderObject = orderPojo.getClass().getMethods(); // 遍歷所有方法 for(int a = 0; a < orderObject.length; a ++){ // 得到每一個(gè)方法名稱(chēng) String name = orderObject[a].getName(); // 判斷獲取需要的(普通的字段都是get/set),這里獲取get方法因?yàn)間et到值才能賦值 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()); //為上面聲明的字段設(shè)置set方法(又稱(chēng)內(nèi)?。? Method setMethod = pd.getWriteMethod(); // 執(zhí)行set setMethod.invoke(newPojo, value); } // 判斷是boolean的字段get時(shí)為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()); //為上面聲明的字段設(shè)置set方法(又稱(chēng)內(nèi)?。? 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. 測(cè)試
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, "類(lèi)型1")); listType.add(new StuType(2, "類(lèi)型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("復(fù)制完的新對(duì)象"+studentDemo1); studentDemo1.setStuId(22); studentDemo1.setStuName("你好啊"); studentDemo1.setStuPrice("啦啦啦"); studentDemo1.setStudentSex("女"); studentDemo1.setStudentAge(20); studentDemo1.setStuNum("沒(méi)有學(xué)號(hào)"); studentDemo1.setTel("沒(méi)有電話(huà)"); 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, "類(lèi)型-1")); listType1.add(new StuType(-2, "類(lèi)型-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("源對(duì)象"+studentDemo); System.out.println("修改復(fù)制后對(duì)象"+studentDemo1); System.out.println("再次查看源對(duì)象"+studentDemo); }
4. 結(jié)果
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java超詳細(xì)教你寫(xiě)一個(gè)斗地主洗牌發(fā)牌系統(tǒng)
這篇文章主要介紹了怎么用Java來(lái)你寫(xiě)一個(gè)斗地主種洗牌和發(fā)牌的功能,斗地主相信大家都知道,同時(shí)也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來(lái)實(shí)現(xiàn)這個(gè)功能,感興趣的朋友跟隨文章往下看看吧2022-03-03SpringBoot整合RocketMQ實(shí)現(xiàn)發(fā)送同步消息
RocketMQ 是一款開(kāi)源的分布式消息中間件,由阿里巴巴開(kāi)源,它具有高可用性、高性能、低延遲等特點(diǎn),廣泛應(yīng)用于阿里巴巴集團(tuán)內(nèi)部以及眾多外部企業(yè)的業(yè)務(wù)系統(tǒng)中,本文給大家介紹了SpringBoot整合RocketMQ實(shí)現(xiàn)發(fā)送同步消息,需要的朋友可以參考下2024-04-04Java詳細(xì)講解堆排序與時(shí)間復(fù)雜度的概念
本文主要介紹了java實(shí)現(xiàn)堆排序以及時(shí)間復(fù)雜度,堆排序這種排序算法是我們經(jīng)常用到的,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04springcloud 服務(wù)降級(jí)的實(shí)現(xiàn)方法
這篇文章主要介紹了springcloud 服務(wù)降級(jí)的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12java開(kāi)發(fā)之鬧鐘的實(shí)現(xiàn)代碼
本篇文章介紹了,在java中鬧鐘的實(shí)現(xiàn)代碼。需要的朋友參考下2013-05-05SpringBoot深入分析講解監(jiān)聽(tīng)器模式上
監(jiān)聽(tīng)器模式,大家應(yīng)該并不陌生,主要的組成要素包括了事件、監(jiān)聽(tīng)器以及廣播器;當(dāng)事件發(fā)生時(shí),廣播器負(fù)責(zé)將事件傳遞給所有已知的監(jiān)聽(tīng)器,而監(jiān)聽(tīng)器會(huì)對(duì)自己感興趣的事件進(jìn)行處理2022-07-0710個(gè)避免Java內(nèi)存泄露的最佳實(shí)踐分享
即使有垃圾回收器的幫助,Java應(yīng)用程序仍然可能遭遇內(nèi)存泄漏問(wèn)題,本文將介紹10個(gè)避免Java內(nèi)存泄漏的最佳實(shí)踐,大家可以根據(jù)需求自己進(jìn)行選擇2025-04-04MyBatis中的XML實(shí)現(xiàn)和動(dòng)態(tài)SQL實(shí)現(xiàn)示例詳解
這篇文章主要介紹了MyBatis中的XML實(shí)現(xiàn)和動(dòng)態(tài)SQL實(shí)現(xiàn),我們可以將XML中重復(fù)出現(xiàn)的內(nèi)容提取出來(lái)放到sql標(biāo)簽中,當(dāng)需要用到sql標(biāo)簽中的內(nèi)容時(shí),用include標(biāo)簽將sql標(biāo)簽中的內(nèi)容引進(jìn)來(lái)即可,感興趣的朋友跟隨小編一起看看吧2024-02-02