最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中BeanUtils.copyProperties的用法(超詳細(xì))

 更新時(shí)間:2023年08月21日 10:20:25   作者:生命不息戰(zhàn)斗不止(王子晗)  
本文介紹了BeanUtils.copyProperties()方法的使用,包括其功能、用法、注意事項(xiàng)和示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

常見(jiàn)場(chǎng)景

我們?nèi)绻袃蓚€(gè)具有很多相同屬性名的JavaBean對(duì)象a和b,想把a(bǔ)中的屬性賦值到b,例如

  • 接口中將接收到的前端請(qǐng)求參數(shù)XxxReqVo,我們想把這個(gè)入?yún)⑥D(zhuǎn)化為XxxQuery對(duì)象作為數(shù)據(jù)庫(kù)的查詢(xún)條件對(duì)象

傳統(tǒng)做法是手動(dòng)set,即

XxxQuery xxxQuery = new XxxQuery();
xxxQuery .setAxx(xxxReqVo.getAxx());
xxxQuery .setBxx(xxxReqVo.getBxx());
xxxQuery .setCxx(xxxReqVo.getCxx());

如果有幾十個(gè)需要賦值的的字段呢?那就很頭疼了org.springframework.beans.BeanUtils,它提供了對(duì)java反射和自省API的包裝。它里面還有很多工具類(lèi),這里我們介紹一下該類(lèi)下面的copyProperties方法,該工具方法可以幫我們大大簡(jiǎn)化這一步

應(yīng)用案例

案例一(兩個(gè)無(wú)關(guān)的類(lèi)做屬性拷貝)

@Data
public class User {
    private String id;
    private String name;
    private String age;
    private String account;
    private String password;
}
@Data
public class Person {
    private String id;
    private String name;
    private String age;
    private String sex;
}
public class Test {
    public static void main(String[] args) {
        User user = new User();
        user.setId("1");
        user.setAge("2");
        user.setName("wzh");
        user.setAccount("wangzh");
        user.setPassword("1111");
        Person person = new Person();
        BeanUtils.copyProperties(user,person);
    }
}

結(jié)果

Person(id=1, name=wzh, age=2, sex=null)

通過(guò)上述測(cè)試我們就可以總結(jié)出相關(guān)結(jié)論,基本用法為

BeanUtils.copyProperties(source,target);

相當(dāng)于把源對(duì)象source的屬性值賦給目標(biāo)對(duì)象target中與源對(duì)象source的中有著同屬性名的屬性,如上述案例中Person作為目標(biāo)對(duì)象與源對(duì)象User中有著共同的同名屬性id,name,age,所以person中的這三個(gè)字段被賦值成功,賦值的數(shù)據(jù)來(lái)源正是user對(duì)象,sex這個(gè)字段是Person類(lèi)所特有的,所以不會(huì)被賦值,同時(shí)還要特別注意賦值操作相關(guān)類(lèi)的屬性一定要有對(duì)應(yīng)的setter/getter,即

  • 源對(duì)象source的屬性拷貝值賦給目標(biāo)對(duì)象target的過(guò)程中,屬性名和屬性類(lèi)型都相同的屬性才能被成功拷貝賦值,例如id,name,age這三個(gè)目標(biāo)對(duì)象的屬性被賦值成功,目標(biāo)對(duì)象中的sex屬性,由于源對(duì)象中沒(méi)有同名的屬性所以沒(méi)法被賦值成功。
  • 做賦值的屬性一定要有對(duì)應(yīng)的setter/getter才能成功賦值

案例二(父子類(lèi)之間做賦值)

這里難度升級(jí)一下,我們不僅僅要演示父子類(lèi)之間做賦值,還要加一個(gè)特征,即在父類(lèi)Person具有String類(lèi)型的age屬性的基礎(chǔ)上,子類(lèi)中定義一個(gè)Integer類(lèi)型的屬性

父類(lèi)Person

@Data
public class Person {
    private String id;
    private String name;
    private String age;
    private String sex;
    public void test(Object obj) {
        System.out.println("test");
    }
    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

子類(lèi)User,類(lèi)內(nèi)含有測(cè)試用的main方法

import org.springframework.beans.BeanUtils;
public class User extends Person{
    private Integer age;
    private String account;
    private String password;
    public <T> T getAge(Boolean isSon) {
        if(isSon == true) {
            return (T) this.age;
        }
        return (T) super.getAge();
    }
    //重載:方法名相同,但返回值數(shù)目/類(lèi)型/不同類(lèi)型返回值的順序非一致,
    // setAge方法滿足重載條件,getAge則無(wú)法滿足重載條件
    public void setAge(String age) {
         super.setAge(age);
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public static void main(String[] args) {
        User user = new User();
        user.setId("1");
        // 設(shè)置父類(lèi)的age屬性值
        user.setAge("23");
        // 設(shè)置子類(lèi)的age屬性值
        user.setAge(2);
        user.setName("wzh");
        user.setAccount("wangzihan06");
        user.setPassword("123456");
        // 獲取子類(lèi)的age屬性,子類(lèi)的age屬性是Interger類(lèi)型,需要用Interger接收
        Integer age1 = user.getAge(true);
        System.out.println(age1);
        // 獲取父類(lèi)的age屬性,子類(lèi)的age屬性是String類(lèi)型,需要用String接收
        String age2 = user.getAge(false);
        System.out.println(age2);
        Person person = new Person();
        // 把子類(lèi)對(duì)象user的屬性值賦值給person,即把user對(duì)象中存儲(chǔ)的Person父類(lèi)相
        // 關(guān)的屬性值賦給父類(lèi)對(duì)象person
        BeanUtils.copyProperties(user,person);
        System.out.println("person:" +person.toString());
        // 反向賦值,即把person的name設(shè)置為null后賦值給user,那么user對(duì)象屬性中繼承自父類(lèi)的這個(gè)
        // 屬性name也會(huì)被重新賦值為空,但它自己所特有的屬性比如account、password不會(huì)受影響
        person.setName(null);
        BeanUtils.copyProperties(person,user);
        System.out.println("user:" +user.toString());
    }
    @Override
    public String toString() {
        return "User{" +
                "age(User)=" + age +
                ", age(Person)=" + super.getAge() +
                ", account='" + account + '\'' +
                ", password='" + password + '\'' +
                ", name(Person)='" + super.getName() + '\'' +
                '}';
    }
}

如上,我們創(chuàng)建的user對(duì)象,我們給這個(gè)對(duì)象的全部屬性做賦值,注意這里user對(duì)象的全部屬性 = user對(duì)象自己特有的屬性(age(Interger類(lèi)型),account,password) + 繼承自父類(lèi)Parent中的屬性(id,name,age(String類(lèi)型),sex)

我們把子類(lèi)對(duì)象user的屬性值賦值給person,即把user對(duì)象中存儲(chǔ)的Person父類(lèi)相關(guān)的屬性值賦給父類(lèi)對(duì)象person

Person person = new Person();//
BeanUtils.copyProperties(user,person);

結(jié)果

person:Person{id='1', name='wzh', age='23', sex='null'}

反向賦值,即把person的name設(shè)置為null后賦值給user,那么user對(duì)象屬性中繼承自父類(lèi)的這個(gè)屬性name被賦值為null,但它自己所特有的屬性比如account、password不會(huì)受影響

person.setName(null);
BeanUtils.copyProperties(person,user);

情況三(帶有POJO/Collection類(lèi)型的屬性)

Life類(lèi),表示是否存活

@Data
@AllArgsConstructor
public class Life {
    private String status; //取值dead是死亡,取值alived是存活
}

分別給User類(lèi)和Person類(lèi)裝配這個(gè)life屬性,而后測(cè)試代碼如下

Life life = new Life("living");
person.setLife(life);
BeanUtils.copyProperties(person,user);
System.out.println("person life:" + person.getLife() + ","
        + "user life:" + user.getLife());

最終打印

person life:Life(status=living),user life:null

由此再次證明一個(gè)觀點(diǎn)

BeanUtils.copyProperties(source,target);

如果source是父類(lèi),target是子類(lèi),那么最終只會(huì)把父類(lèi)中的屬性值同步給子類(lèi)中繼承自父類(lèi)的屬性,子類(lèi)所獨(dú)有的屬性不會(huì)受到影響

去掉這兩個(gè)類(lèi)的繼承關(guān)系,重新演示

 User user = new User();
 Person person = new Person();
 Life personLife = new Life("person living");
 Life userLeft = new Life("son living");
 person.setLife(personLife);
 user.setLife(userLeft);
 BeanUtils.copyProperties(person,user);
 System.out.println("person life:" + person.getLife() + ","
         + "user life:" + user.getLife() );
 System.out.println(person.getLife() == user.getLife());

打印

person life:Life(status=living),user life:Life(status=living)
true

賦值成功,而且同時(shí)可以看出BeanUtils.copyProperties中引用類(lèi)型的屬性間的拷貝方式是淺拷貝,淺拷貝即僅僅是把源對(duì)象person中l(wèi)ife屬性的引用賦值給目標(biāo)對(duì)象user的life屬性,而且就算目標(biāo)對(duì)象user本身就具有l(wèi)ife屬性值,也會(huì)在copyProperties的過(guò)程中被源對(duì)象person中l(wèi)ife對(duì)象覆蓋它原本的life對(duì)象這個(gè)屬性

情況四(兩個(gè)帶有泛型屬性的類(lèi)做屬性拷貝)

@Data
public class Person<T> {
    private String id;
    private String name;
    private String age;
    private String sex;
    private List<T> list;
}
package com.example.demo2.test.gneric;
import com.example.demo2.mode.Life;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
@Data
@Slf4j
public class User<T> {
    private Life life;
    private String account;
    private String password;
    private List<T> list;
    public static void main(String[] args) {
        User user = new User();
        Person person = new Person();
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        List<String> list2 = new ArrayList<String>();
        list2.add("A");
        list2.add("B");
        list2.add("C");
        user.setList(list1);
        person.setList(list2);
        BeanUtils.copyProperties(user,person);
        log.info("user:{}",user);
        log.info("person:{}",person);
        // 結(jié)果為true,可見(jiàn)賦值的時(shí)候直接是把list1的引用直接賦值給了list2
        log.info("isEqual:{}",person.getList() == user.getList());
        // list2沒(méi)有變化,可見(jiàn)我們沒(méi)法直接對(duì)list列表間做賦值
        BeanUtils.copyProperties(list1,list2);
        log.info("list2:{}",list2);
    }
}

情況分析泛型集合的作用是在編譯期,過(guò)了編譯期,泛型的影響會(huì)通過(guò)泛型擦除機(jī)制被立馬被擦除掉,在程序運(yùn)行期間即不再有實(shí)際意義,而我們分析源碼可在,屬性拷貝是利用的反射機(jī)制,即在程序運(yùn)行期間通過(guò)getter/setter來(lái)做屬性拷貝的,所以泛型對(duì)屬性拷貝沒(méi)有影響

結(jié)果分析list屬性被成功拷貝,同時(shí)我們發(fā)現(xiàn)person.getList和user.getList()完全是同一個(gè)list對(duì)象,可見(jiàn)賦值的時(shí)候直接是把list1的引用直接賦值給了list2,嘗試把list1賦值給list2,最終結(jié)果list2沒(méi)有變化,可見(jiàn)我們沒(méi)法直接直接對(duì)list列表間做賦值

14:28:43.065 [main] INFO com.example.demo2.test.gneric.User - user:User(life=null, account=null, password=null, list=[1, 2, 3])
14:28:43.073 [main] INFO com.example.demo2.test.gneric.User - person:Person(id=null, name=null, age=null, sex=null, list=[1, 2, 3])
14:28:43.073 [main] INFO com.example.demo2.test.gneric.User - isEqual:true
14:28:43.105 [main] INFO com.example.demo2.test.gneric.User - list2:[A, B, C, D]

到此這篇關(guān)于java中BeanUtils.copyProperties的用法(超詳細(xì))的文章就介紹到這了,更多相關(guān)java BeanUtils.copyProperties內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8中常用的日期時(shí)間工具類(lèi)總結(jié)

    Java8中常用的日期時(shí)間工具類(lèi)總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java8中常用的三個(gè)日期時(shí)間工具類(lèi),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-07-07
  • 詳解JDBC使用

    詳解JDBC使用

    JDBC(Java Database Connectivity),即Java數(shù)據(jù)庫(kù)連接,是一種用于執(zhí)行SQL語(yǔ)句的Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供同一訪問(wèn),它由一組用Java語(yǔ)言編寫(xiě)的類(lèi)和接口組成。
    2017-05-05
  • Java判斷一個(gè)時(shí)間是否在當(dāng)前時(shí)間區(qū)間代碼示例

    Java判斷一個(gè)時(shí)間是否在當(dāng)前時(shí)間區(qū)間代碼示例

    這篇文章主要給大家介紹了關(guān)于使用Java判斷一個(gè)時(shí)間是否在當(dāng)前時(shí)間區(qū)間的相關(guān)資料,在日常開(kāi)發(fā)中我們經(jīng)常會(huì)涉及到時(shí)間的大小比較或者是判斷某個(gè)時(shí)間是否在某個(gè)時(shí)間段內(nèi),需要的朋友可以參考下
    2023-07-07
  • IntelliJ IDEA2020.1 Mac maven sdk 全局配置

    IntelliJ IDEA2020.1 Mac maven sdk 全局配置

    這篇文章主要介紹了IntelliJ IDEA2020.1 Mac maven sdk 全局配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • MyBatis-Plus多數(shù)據(jù)源的示例代碼

    MyBatis-Plus多數(shù)據(jù)源的示例代碼

    本文主要介紹了MyBatis-Plus多數(shù)據(jù)源的示例代碼,包括依賴(lài)配置、數(shù)據(jù)源配置、Mapper 和 Service 的定義,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • servlet實(shí)現(xiàn)簡(jiǎn)單的權(quán)限管理和敏感詞過(guò)濾功能

    servlet實(shí)現(xiàn)簡(jiǎn)單的權(quán)限管理和敏感詞過(guò)濾功能

    JavaEE課要求用servlet和過(guò)濾器實(shí)現(xiàn)權(quán)限管理和敏感詞過(guò)濾功能,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • MyBatis中的properties配置(推薦)

    MyBatis中的properties配置(推薦)

    這篇文章給大家介紹了MyBatis中的properties配置,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-12-12
  • SpringBoot中集成串口通信的項(xiàng)目實(shí)踐

    SpringBoot中集成串口通信的項(xiàng)目實(shí)踐

    本文主要介紹了SpringBoot中集成串口通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Java中的static關(guān)鍵字修飾屬性和方法(推薦)

    Java中的static關(guān)鍵字修飾屬性和方法(推薦)

    這篇文章主要介紹了Java中的static關(guān)鍵字修飾屬性和方法,包括哪些成員屬性可以被static修飾,靜態(tài)屬性的訪問(wèn)方法示例詳解,需要的朋友可以參考下
    2022-04-04
  • 使用springmvc參數(shù)接收boolean類(lèi)型參數(shù)的問(wèn)題

    使用springmvc參數(shù)接收boolean類(lèi)型參數(shù)的問(wèn)題

    這篇文章主要介紹了使用springmvc參數(shù)接收boolean類(lèi)型參數(shù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論

大方县| 满洲里市| 嘉义市| 宜君县| 新郑市| 福鼎市| 乌兰察布市| 保德县| 马龙县| 榆树市| 织金县| 呼图壁县| 景德镇市| 泉州市| 榆林市| 海丰县| 铜梁县| 贡觉县| 开江县| 中牟县| 巴彦淖尔市| 临漳县| 屏边| 山西省| 仲巴县| 沙洋县| 桐庐县| 安吉县| 竹北市| 阳谷县| 原平市| 商丘市| 长汀县| 江油市| 阿巴嘎旗| 云阳县| 凌海市| 镇雄县| 库伦旗| 嵩明县| 温州市|