apc电源是什么牌子,apc电源手册

  

  前言通常,当我们从数据库中查询po对象并返回到前端时,会有另一个对象vo。这时候我们需要把po的值复制到vo。如果是你,你会怎么做?   

  

  有时候除了复制,我们还要求po参数值的变化不能影响vo,也就是po和vo是两个独立的个体。这个时候我们需要做什么?   

  

  带着这些问题,我们来看看今天关于对象复制的知识点。   

  

  1.什么是轻拷贝和深拷贝浅拷贝?   

  

  对于基本数据类型的成员变量,light copy直接传递值,即将属性值复制到新的成员变量中。对于引用数据类型的成员变量,比如数组或者某个类的对象,轻拷贝指的是引用的传递,即把成员变量的引用(内存地址)拷贝到新的成员变量上,并且都指向同一个case。修改一个对象中成员变量的值会影响另一个对象中成员变量的值。深拷贝   

  

  对于基本数据类型,深度复制复制所有基本数据类型的成员变量的值。对于引用数据类型的成员变量,深度复制申请新的存储空间,复制引用对象引用的对象,即复制整个对象。因此,修改一个对象中成员变量的值不会影响另一个对象中成员变量的值。二。浅抄1。clone实现了clone()方法的可克隆重写,声明public调用super.clone()copydemo。   

  

  @ datapublicclasscopydemoeimplementscloneable { private intage;privateUseruser@ OverridepublicCopyDemoclone(){ try { CopyDemoclone=(copy demo)super . clone();returnclone} catch(clonenotsupportedexception){ thrownewAssertionError();} } }用户   

  

  @ data public class user { privateStringname;}使用   

  

  @ servicepublicsclasscopyservicedemo { publicstaticvoidmain(string args){ copydomosource=newCopyDemo();source . setage(10);user user=new user();User.setName(“用户旧名称”);source.setUser(用户);copydometarget=source . clone();System.out.println('已更改   

变之前");        System.out.println("source:"+source.getAge());        System.out.println("target:"+target.getAge());        System.out.println("source-user:"+source.getUser().getName());        System.out.println("target-user:"+target.getUser().getName());        source.setAge(20);        user.setName("user-新名字");        System.out.println("改变之后");        System.out.println("source:"+source.getAge());        System.out.println("target:"+target.getAge());        System.out.println("source-user:"+source.getUser().getName());        System.out.println("target-user:"+target.getUser().getName());    }}结果

  

改变之前source:10target:10source-user:user-旧名字target-user:user-旧名字改变之后source:20target:10source-user:user-新名字target-user:user-新名字从以上结果可以看出

  

修改 source 的 age,并不会影响到拷贝之后的 target 的 age修改 source 的 user 的 name,会影响到拷贝之后的 targe 的 user 的 name,因为 target 的 user 跟 source 的 user 所指向的是同一个 user 实例。2、Apache BeanUtils(不推荐)Apache BeanUtils 属于比较古老的工具类,由于存在性能问题,阿里巴巴手册明确禁止使用该工具类

  

性能差的原因是:力求做得完美, 在代码中增加了非常多的校验、兼容、日志打印等代码,过度的包装导致性能下降严重。

  

  

3、Spring BeanUtilsSpring BeanUtils 和上面所提到的 apche 得很像,但是在效率上比 apache 得更高

  

Spring BeanUtils 的 copyProperties() 方法,第一个是源对象,第二个是目标对象。和 Apache BeanUtils 正好相反,要注意避免踩坑。

  

import org.springframework.beans.BeanUtils;CopyDemo target=new CopyDemo();BeanUtils.copyProperties(source, target);4、Spring BeanCopierSpring 还为我们提供了一种基于 Cglib 的浅拷贝方式 BeanCopier,引入 spring-core 依赖包后即可使用,它被认为是取代 BeanUtils 的存在。

  

以下是自己封装的工具类:

  

import org.springframework.cglib.beans.BeanCopier;public static <T> T copyByClass(Object src, Class<T> clazz) {  BeanCopier copier = BeanCopier.create(src.getClass(), clazz, false);  T to = newInstance(clazz);  copier.copy(src, to, null);  return to;}public static <T> T newInstance(Class<?> clazz) {  try {      return (T) clazz.newInstance();    } catch (InstantiationException e) {        throw new RuntimeException(e);    } catch (IllegalAccessException e) {        throw new RuntimeException(e);    }}public static void copyByObj(Object src, Object dist) {  BeanCopier copier = BeanCopier    .create(src.getClass(), dist.getClass(), false);  copier.copy(src, dist, null); }使用

  

CopyDemo target = copyByClass(source, CopyDemo.class);三、深拷贝1、构造方法-new手动 new 新的对象,一个属性一个属性的 set 过去,属性多的话,这样非常麻烦

  

    public static void main(String<> args) {        CopyDemo source= new CopyDemo();        source.setAge(10);        User user=new User();        user.setName("user-旧名字");        source.setUser(user);        CopyDemo target=new CopyDemo();        target.setAge(source.getAge());        User targetUser=new User();        targetUser.setName(source.getUser().getName());        target.setUser(targetUser);        System.out.println("改变之前");        System.out.println("source:"+source.getAge());        System.out.println("target:"+target.getAge());        System.out.println("source-user:"+source.getUser().getName());        System.out.println("target-user:"+target.getUser().getName());        source.setAge(20);        user.setName("user-新名字");        System.out.println("改变之后");        System.out.println("source:"+source.getAge());        System.out.println("target:"+target.getAge());        System.out.println("source-user:"+source.getUser().getName());        System.out.println("target-user:"+target.getUser().getName());    }改变之前source:10target:10source-user:user-旧名字target-user:user-旧名字改变之后source:20target:10source-user:user-新名字target-user:user-旧名字Process finished with exit code 02、重载 clone()方法拷贝的对象中还包含其他对象的话,包含的对象也需要重写 clone 方法super.clone()其实是浅拷贝,所以在重写 CopyDemo 类的 clone()方法时,user 对象需要调用 user.clone()重新赋值CopyDemo

  

@Datapublic class CopyDemo implements Cloneable{    private int age;    private User user;    @Override    public CopyDemo clone() {        try {            CopyDemo copyDemo = (CopyDemo) super.clone();            copyDemo.setUser(this.user.clone());            return copyDemo;        } catch (CloneNotSupportedException e) {            throw new AssertionError();        }    }}User

  

@Datapublic class User implements Cloneable{    private String name;    @Override    public User clone() {        try {            User clone = (User) super.clone();            return clone;        } catch (CloneNotSupportedException e) {            throw new AssertionError();        }    }}使用

  

CopyDemo target = source.clone();3、Apache Commons Lang 序列化方式Java 提供了序列化的能力,我们可以先将源对象进行序列化,再反序列化生成拷贝对象。但是,使用序列化的前提是拷贝的类(包括其成员变量)需要实现 Serializable 接口。Apache Commons Lang 包对 Java 序列化进行了封装:SerializationUtils,我们可以直接使用它。

  

@Datapublic class CopyDemo implements Serializable {    private static final long serialVersionUID = -9820808986091860L;    private int age;    private User user;}@Datapublic class User implements Serializable {    private static final long serialVersionUID = 1900781036567192607L;    private String name;}使用

  

import org.apache.commons.lang3.SerializationUtils;CopyDemo target = SerializationUtils.clone(source);4、json 转化方式利用 json 将对象转为 json,再将 json 转为对象,本质上是反射

  

//对象String jsonString = JSON.toJSONString(source);CopyDemo target = JSON.parseObject(jsonString, CopyDemo.class);//集合List<CopyDemo> sourceList=Lists.newArrayList();String jsonString = JSON.toJSONString(sourceList);List<CopyDemo> targetList = JSON.parseArray(json,CopyDemo.class);5、Orikaorika 是深拷贝,但是遇到多层签到数组,clone 会有问题,谨慎使用

  

四、总结如果对象中只有基本数据类型或者引用数据类型不会改动,则可以使用浅拷贝

  

如果存在引用数据类型且会改动,则可以使用深拷贝

  

具体使用拷贝中的哪个方法,需要具体情况具体分析,比如性能考虑、便捷考虑、依赖引入的考虑等等。

  

今天只是列出了一些常用的方法,还有其他的拷贝方法,可以自行搜索,多学习,多实践。

  


  


  

我是臻大虾,你的支持是对我不断创作的极大鼓励,咱们下期见。

  

关注公众号:臻大虾 分享java后端技术干货,每天进步一点点

  

  

相关文章