日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring BeanUtils.copyProperties浅拷贝之特殊的Boolean

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring BeanUtils.copyProperties浅拷贝之特殊的Boolean 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

在開發過程中, 在數據庫查詢和接口調用過程中,為了隔離,我們往往會將查詢出來的對象(包括數據庫返回和接口返回)和對外提供的實體對象隔離開來。此時就需要把一個對象的屬性拷貝到目標對象中
通常有2種做法:
1、一個一個set b.setField(a.getField());
2、使用拷貝的工具類,比方說 BeanUtils.copyProperties (因為他們的類結構和屬性字段大多是類似的)

對于字段比較多的場景,使用BeanUtils明顯更加簡潔

那么問題來了,
BeanUtils對于對象中包含的對象也能夠幫我們進行拷貝嗎?
如果會進行拷貝,它幫我們做的拷貝是深拷貝還是淺拷貝?

深淺拷貝 的主要區別就是:復制的是引用還是復制的是值。

如果僅僅復制了引用,也就是說,復制之后,原來的變量和新的變量指向同一個地址,彼此之間的操作會互相影響,為 淺拷貝。
而如果是在堆中重新分配內存,擁有不同的地址,但是值是一樣的,復制后的對象與原來的對象是完全隔離,互不影響,就是深拷貝。

BeansUtils 實戰

創建兩個類 Student和Course 以及一個目標類StudentEntity(和Student類除了名字以外其余字段和結構都完全一致)

public class Student {private String name;private Integer age;/*** 是否已畢業* */private Boolean isGraduated;private Course course;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Boolean getGraduated() {return isGraduated;}public void setGraduated(Boolean graduated) {isGraduated = graduated;}public Course getCourse() {return course;}public void setCourse(Course course) {this.course = course;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", isGraduated=" + isGraduated +", course=" + course +'}';} public class Course {private String courseName;private Integer score;public String getCourseName() {return courseName;}public void setCourseName(String courseName) {this.courseName = courseName;}public Integer getScore() {return score;}public void setScore(Integer score) {this.score = score;}@Overridepublic String toString() {return "Course{" +"courseName='" + courseName + '\'' +", score=" + score +'}';} }

測試類:

public class Test {@org.junit.Testpublic void testCopyStudent(){Student student = new Student();student.setName("chenpp");student.setAge(21);student.setGraduated(true);Course course = new Course();course.setCourseName("Chinese");course.setScore(100);student.setCourse(course);StudentEntity copyStudent = new StudentEntity();BeanUtils.copyProperties(student, copyStudent);System.out.println("拷貝后的對象" + copyStudent);copyStudent.getCourse().setCourseName("Math");System.out.println("修改拷貝后的course,原來的對象" + student);} }


從上面的代碼可以看出,spring-beans提供的BeanUtils.copyProperties對于外層的屬性無論是基本數據類型還是引用數據類型都會進行拷貝,使用的是淺拷貝

Boolean和boolean類型的拷貝

在使用過程中,發現如果Student的isGraduated字段的set方法定義成isGraduated(),那么拷貝就會失敗

public class Student {private String name;private Integer age;/*** 是否已畢業* */private Boolean isGraduated;private Course course;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Boolean isGraduated() {return isGraduated;}public void setIsGraduated(Boolean isGraduated) {this.isGraduated = isGraduated;} }

測試結果: isGraduated字段沒有被拷貝

跟蹤下源碼看看是什么原因?

private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)throws BeansException {Class<?> actualEditable = target.getClass();//...//根據targetClass獲取其屬性描述器PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);//...for (PropertyDescriptor targetPd : targetPds) {Method writeMethod = targetPd.getWriteMethod();if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {//根據sourceClass獲取其屬性描述器(和targetClass執行的方法一樣)PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null) {//如果源對象的readMethod為空,就無法獲取到源對象的值,也就無法通過反射進行賦值Method readMethod = sourcePd.getReadMethod();if (readMethod != null &&ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {try {//...writeMethod.invoke(target, value);}catch (Throwable ex) {}}}}}}

其源碼路徑如下
BeanUtils.getPropertyDescriptor -->
? ? ?CachedIntrospectionResults.forClass(clazz) -->
? ? ?? ? ? new CachedIntrospectionResults(beanClass) -->
? ? ?? ? ?? ? ? Introspector.getBeanInfo(Class<?> beanClass) -->
? ? ?? ? ?? ? ?? ? ? Introspector.getBeanInfo()

private BeanInfo getBeanInfo() throws IntrospectionException {// the evaluation order here is import, as we evaluate the// event sets and locate PropertyChangeListeners before we// look for properties.BeanDescriptor bd = getTargetBeanDescriptor();MethodDescriptor mds[] = getTargetMethodInfo();EventSetDescriptor esds[] = getTargetEventInfo();//關鍵方法,獲取目標對象的屬性信息 這里就是StudentEntityPropertyDescriptor pds[] = getTargetPropertyInfo();int defaultEvent = getTargetDefaultEventIndex();int defaultProperty = getTargetDefaultPropertyIndex();return new GenericBeanInfo(bd, esds, defaultEvent, pds,defaultProperty, mds, explicitBeanInfo);} private PropertyDescriptor[] getTargetPropertyInfo() {Method methodList[] = getPublicDeclaredMethods(beanClass);for (int i = 0; i < methodList.length; i++) {//...Class<?>[] argTypes = method.getParameterTypes();Class<?> resultType = method.getReturnType();int argCount = argTypes.length;//...if (argCount == 0) {if (name.startsWith(GET_PREFIX)) {// Simple getterpd = new PropertyDescriptor(this.beanClass, name.substring(3), method, null);} else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) {// Boolean getterpd = new PropertyDescriptor(this.beanClass, name.substring(2), method, null);}}//...}}

從這里就可以看到,如果屬性是Boolean類型,其read方法需要以getXXX命名,而對于boolean類型,需要以isXX命名

根據class獲取對應的屬性信息之后,會緩存在propertyDescriptorCache里,debug可以看到StudentEntity的isGraduated字段對應的readMethod為空(Student的isGraduated字段對應的readMethod也為空)

總結

BeanUtils.copyProperties主要是通過反射實現的淺拷貝,如果對象都是單一的屬性或者子對象不涉及到改動,可以BeanUtils進行拷貝
在拷貝的時候注意對于Boolean類型字段,其readMethod需要以getXXX來命名

總結

以上是生活随笔為你收集整理的spring BeanUtils.copyProperties浅拷贝之特殊的Boolean的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 合欢视频污| 日产精品久久久 | 特一级黄色 | 亚洲国产欧美另类 | 成人黄色激情网 | 尤物视频在线观看 | 91亚洲国产成人精品性色 | 欧美乱妇18p| 亚洲美女视频在线观看 | 久久免费精彩视频 | 玖玖国产精品视频 | 中文文字幕文字幕高清 | 久久成人国产精品入口 | 伊伊总综合网 | 国产精品我不卡 | 海角社区在线 | 欧美丰满老妇性猛交 | 精品区一区二区 | 欧美日韩爱爱 | 欧美色v | 欧美激情福利 | 日韩三级一区二区三区 | 亚洲国产视频一区二区三区 | 国产日产精品一区 | 丰满人妻综合一区二区三区 | 国产免费的av | 污视频在线网站 | 中文字幕精品无码亚 | 国产精品久久久久久久久晋中 | 羞羞漫画在线播放 | 亚洲风情亚aⅴ在线发布 | av片在线免费观看 | 少妇一级淫片免费放中国 | 夜噜噜| 夜色资源网 | 桃谷绘里香在线观看 | 欧美整片第一页 | 亚洲午夜精选 | 久久精品综合视频 | 国产综合区 | wwwww在线观看| www.色天使| 国产午夜精品免费一区二区三区视频 | 日日夜夜拍 | 91精品一区二区 | 91精品国产综合久久久蜜臀 | 9i看片成人免费高清 | 一级黄色短视频 | 婷婷久久伊人 | 欧美高清v| 波多野吉衣久久 | 久久国产精品网站 | 瑟瑟在线观看 | www.av在线播放 | 久操不卡| 沟厕沟厕近拍高清视频 | 伊人天堂av| 911精品| 波多野结衣黄色 | 琪琪成人 | 国产中出视频 | 奇米影视首页 | 久久久久久久福利 | 亚洲一区二区三区日韩 | 欧美黄色大片在线观看 | 色射综合| 久久亚洲国产 | 精品人妻视频在线 | 欧美国产成人精品一区二区三区 | 91亚洲国产成人久久精品麻豆 | 久久午夜激情 | 亚洲自拍偷拍在线 | 亚洲欧美精品aaaaaa片 | 一区二区xxx| 久久久精品电影 | 中文字幕日韩欧美在线 | 日韩欧美亚洲国产精品字幕久久久 | 国产91丝袜在线播放 | 欧美丰满老妇熟乱xxxxyyy | 国产精品自拍99 | av免费在线观看网址 | 久久久精品国产sm调教网站 | 青草伊人网 | 在线播放www | 中文字幕专区 | 成人激情免费 | 黄色免费视屏 | 日韩精品不卡 | 日韩精美视频 | 天天噜日日噜 | 午夜亚洲AV永久无码精品蜜芽 | 国产伦精品一区二区三区视频孕妇 | 亚洲国内精品 | 成人av一区二区在线观看 | 欧美 日韩 国产 一区 | 日日爽爽 | 狠狠狠 | 熟妇高潮一区二区三区 | 波多野结衣中文字幕在线 |