所有分类
  • 所有分类
  • 未分类

Spring工具类-BeanUtils为什么是浅拷贝

简介

说明

本文用实例介绍Spring的BeanUtils的拷贝原理。

概述

Spring的BeanUtils是浅拷贝:

  1. 如果要拷贝的成员是基本数据类型,它会拷贝成员的值,相当于数据是独立的。这里的基本数据类型包括基础类型和包装类型,例如:Integer、int、String、Long、long等)
  2. 如果要拷贝的成员不是基本数据类型,就拷贝引用地址(使用同一个引用地址(也就是:同一个对象))。

实例

代码

Entity

User

package com.knife.entity;

import lombok.Data;

@Data
public class User {
    private Long id;

    private String userName;

    private UserDetail userDetail;
}

UserDetail

package com.knife.entity;

import lombok.Data;

@Data
public class UserDetail {
    private Long id;

    private String address;
}

Controller

package com.knife.controller;

import com.knife.entity.User;
import com.knife.entity.UserDetail;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/test")
    public String test() {
        User user = new User();
        user.setId(1L);
        user.setUserName("Tony");

        UserDetail userDetail = new UserDetail();
        userDetail.setId(2L);
        userDetail.setAddress("上海");
        user.setUserDetail(userDetail);

        User user1 = new User();
        BeanUtils.copyProperties(user, user1);

        return "test success";
    }
}

测试

打断点:

访问:http://localhost:8080/test

结果:

可以看到,user和user1它们的userDetail成员是同一个对象:{UserDetail@6602}

原理分析

打断点

访问:http://localhost:8080/test

运行到这个地方:

BeanUtils#copyProperties(java.lang.Object, java.lang.Object, java.lang.Class<?>, java.lang.String…)

如下图所示:

可以看到,targetPds里边包含了目标对象的所有成员,依次对它处理,看它下半部分的代码:

可以发现,它是使用反射,先调用源对象的getXxx方法获取值,再调用目标对象的setXxx方法将值设置进去。

所以,当成员是基本类型之外的对象时,它getXxx会获取到引用地址,setXxx会将引用地址设置进去,所以会共用同一个对象。

深拷贝的方案

方案1:使用JSON

先将源对象转化为json字符串,再将json字符串转为对象。

JSON工具类见:SpringBoot-封装JSON工具类(基于Jackson) – 自学精灵

方案2:使用serializable接口

使用序列化接口,结合内存输入输出流。 ​

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录