精华内容
下载资源
问答
  • 就比如 A a=new A(); 将a复制给b 但他们两是不同的两个对象,a==b//false 有什么方法吗,不用clone
  • Java对象复制三种方式

    千次阅读 2021-02-12 09:36:34
    Java对象复制三种方式概述在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也...

    Java对象的复制三种方式

    概述

    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。例如下面程序展示的情况:

    bd48740b69ba7d84783d11a72cd1016e.png

    结果:

    831c28763299a93e6a9416eef4f85b3e.png

    为什么改变学生2的学号,学生1的学号也发生了变化呢?

    原因出在(stu2 = stu1) 这一句。该语句的作用是将stu1的引用赋值给stu2,

    这样,stu1和stu2指向内存堆中同一个对象。如图:

    2017e977b6a97856e51c66f1d9cbed76.png

    那么,怎么能干干净净清清楚楚地复制一个对象呢。在 Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求有很多途径,

    (1)将A对象的值分别通过set方法加入B对象中;

    (2)通过重写java.lang.Object类中的方法clone();

    (3)通过org.apache.commons中的工具类BeanUtils和PropertyUtils进行对象复制;

    (4)通过序列化实现对象的复制。

    2.将A对象的值分别通过set方法加入B对象中

    对属性逐个赋值,本实例为了演示简单就设置了一个属性:

    5662878de832c2998daf0bbd1db970e0.png

    我们发现,属性少对属性逐个赋值还挺方便,但是属性多时,就需要一直get、set了,非常麻烦。

    3.重写java.lang.Object类中的方法clone()

    先介绍一下两种不同的克隆方法,浅克隆(ShallowClone)和深克隆(DeepClone)。

    在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制,下面将对两者进行详细介绍。

    3.1浅克隆

    一般步骤:

    1.被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)

    2.覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法)

    ec261c5c475e6247c0a84e641869b05e.png

    ede1b4b1ed63c41f8735fe00e8d476de.png

    在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

    简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

    f06f2279a27f0c07fe1583d1d562b603.png

    在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆

    3.2深克隆

    f7d7365fccedc0178f2cd57b3c79f994.png

    4d757a10137decfe3d836842bcded1d8.png

    e410a69c75a82c17b4e9870611730318.png

    怎么两个学生的地址都改变了?

    原因是浅复制只是复制了addr变量的引用,并没有真正的开辟另一块空间,将值复制后再将引用返回给新对象。

    为了达到真正的复制对象,而不是纯粹引用复制。我们需要将Address类可复制化,并且修改clone方法,完整代码如下:

    0ec4a01b26234411cd94c333c23b1f8b.png

    9449c1a238c7cd42c66eea7fcdf681c5.png

    1ecd3230f2f429e74d8ece89362273f3.png在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

    简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。

    d7200d03eb6e1fc50a10e8e94ea5c04a.png

    在Java语言中,如果需要实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。

    (如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。)

    4.工具类BeanUtils和PropertyUtils进行对象复制

    701b782f8bbdb033a73661ea034dceda.png

    这种写法无论多少种属性都只需要一行代码搞定,很方便吧!除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而PropertyUtils不支持这个功能,但是速度会更快一些。在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。

    5.通过序列化实现对象的复制

    序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

    b85b515656b31ac99a826f0366771e7a.png

    926d96356b3a6d778d7514ed51157c93.png

    b51d6e04e34d3fd7c30f95d886ce62d1.png

    调用ByteArrayOutputStream或ByteArrayInputStream对象的close方法没有任何意义。这两个基于内存的流只要垃圾收集器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放。

    dc6cc21d54522beb05c38d826c1fc488.png

    修改克隆的Person对象person1关联的汽车对象的品牌属性,原来的Person对象person关联的汽车不会受到任何影响,因为在克隆Person对象时其关联的汽车对象也被克隆了。

    基于序列化和反序列化实现的克隆不仅仅时深度克隆,更重要的是通过范型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译期完成的,不是在运行时抛出异常,这种方案明显优于使用Object类的clone方法克隆对象。

    展开全文
  • JAVA复制对象给另一个对象

    千次阅读 2016-06-25 22:40:15
    JAVA复制对象给另一个对象  标签: javahibernateobject 2012-03-23 16:46 14881人阅读 评论(0) 收藏 举报  分类:   J2SE(113)  版权声明:本文为博主原创文章,未经博主允许...
     

    JAVA复制对象给另一个对象 

    标签: javahibernateobject
      14881人阅读  评论(0)  收藏  举报
      分类:
     

    今天算是遇到一个问题了。相当苦恼。

    需求如下:有2个相同id的对象,但它们的值不同。其中一个对象要用到另一个对象的属性值。

    由于在hibernate的sessionFactory().getSession中不能存在2个相同id的对象。故此,想出复制对象。

    找了很多地方,发现有2种方法可以达到复制对象的目的,只是最后这种方法还是没有解决我的问题。仅此记下来吧。

    1,克隆clone

    Java支持克隆一个对象的值到另一个对象,简单的克隆和深度克隆,深度克隆可能包括继承,嵌套,没有用到,所以也就没怎么去研究它。

    首先,克隆的对象需要实现 Cloneable接口,重写其中的clone()方法,为了使clone()方法在外部可用,需要将重写的方法访问修饰符改成public级别。

    [java]  view plain  copy
     print ?
    1. @Override  
    2.     public Object clone() throws CloneNotSupportedException {  
    3.         return super.clone();  
    4.     }  

    [java]  view plain  copy
     print ?
    1. dv=(Deliverymanreport)deliverymanreport.clone();//克隆对象  

    dv是deliverymanreport克隆的一个对象。它拥用克隆后的属性和方法。


    2,序列化和反序列化Serializable

    序列化的对象要实现Serializable接口才能实现序列化。

    序列化后,通过反序列化可以得到和当前对象一样的对象。它比克隆来得更准备。但也就不一定最好,如果这个对象在之前被修改,序列化后可能就会出问题了。

    [java]  view plain  copy
     print ?
    1. ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
    2. ObjectOutputStream out= new ObjectOutputStream(byteOut);  
    3. out.writeObject(deliverymanreport);//写对象,序列化  
    4. ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());   
    5.  dv=(Deliverymanreport)in.readObject(); //读对象,反序列化  

    序列化经常用于文件传递的读取。尤其是在缓存中用得比较多,通过序列化可以将对象缓存在硬盘中。这在登录系统缓存用户权限和角色等信息最常见。而用对克隆对象,也不失为一种很好的方法。
    展开全文
  • java复制对象的几种方法

    千次阅读 2020-04-11 15:50:42
    最近业务要复制对象,但我又不想一个个的去get、set,于是就网上找了三种复制对象的方法。 一,浅层复制。 1.需要复制的类实现Cloneable接口; 2.复写clone()方法; import java.lang.Cloneable;; public class ...

    最近业务要复制对象,但我又不想一个个的去get、set,于是就网上找了三种复制对象的方法。
    一,浅层复制。
    1.需要复制的类实现Cloneable接口;
    2.复写clone()方法;
    import java.lang.Cloneable;;

    public class OrderVO implements Cloneable {

    private int orderID;
    
    private int userID;
    
    private double orderAmount;
    
    public int getOrderID() {
    	return orderID;
    }
    
    public void setOrderID(int orderID) {
    	this.orderID = orderID;
    }
    
    public int getUserID() {
    	return userID;
    }
    
    public void setUserID(int userID) {
    	this.userID = userID;
    }
    
    public double getOrderAmount() {
    	return orderAmount;
    }
    
    public void setOrderAmount(double orderAmount) {
    	this.orderAmount = orderAmount;
    }
    
    @Override
    public Object clone() {
    	OrderVO vo = null;
    	try {
    	vo = (OrderVO) this.clone();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return vo;
    	
    }
    

    }
    二,深层复制。
    在浅层复制中,只是值类型的成员变量,对于引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。这样修改了复制对象的引用值,原对象的值也会改变,这当然是不对的。
    解决方法有2种,一是把变量的引用类型也设置为克隆对象;二是直接实现序列化,对对象进行IO操作,读取/写入。可想而知,方法一比较麻烦。
    三、工具类BeanUtils和PropertyUtils进行对象复制
    无论是实现clone()方法,还是进行IO操作,都是比较麻烦的,代码也多,这时,可以利用java的工具类,一行搞定。
    BeanUtils和PropertyUtils主要的区别在于,BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而PropertyUtils不支持这个功能。因为不支持,所以速度会更快一些。在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。

        OrderVO vo1 = new OrderVO(); // 原对象
    	OrderVO vo2 = new OrderVO(); // 目标对象
    	try {
    		BeanUtils.copyProperties(vo2, vo1);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    

    注意,如果是要循环复制对象,切不可把new新对象的语句写在循环外部,不然每次的新值都是一个引用地址。

    展开全文
  • import org.springframework.beans.BeanUtils; //将User对象中的数据映射到newUser 中 User newUser = new User(); BeanUtils.copyProperties(user, newUser);
    import org.springframework.beans.BeanUtils;
    
    //将User对象中的数据映射到newUser 中
    User newUser = new User();
    BeanUtils.copyProperties(user, newUser);

     

    展开全文
  • import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(源对象, 目标对象);
  • 那么该篇文章介绍一个方法,简单粗暴,就是使用BeanUtils。 简单示例: Dog,里面有两个字段(构造方法,setget省略): 而SpecialDog里面有三个字段,其中name和age是一样的,但是多了一个nickName字段, ...
  • Java对象的快速复制的几种方式

    万次阅读 2018-07-25 18:01:08
    对象的克隆是指创建一个新的对象,且新的对象的状态与原始对象的状态相同。当对克隆的新对象进行修改时,不会影响原始对象的状态。 注释:clone()是object类的protected 方法,只有类的对象自己可以克隆自己 ...
  • 代码: BeanUtils.copyProperties(对象1,对象2); 如此即可把对象1的值赋值给对象2.
  • Java BeanUtils对象复制工具类及方法

    千次阅读 2018-12-14 17:02:37
    1. BeanUtils.copyProperties(Object source, Object target...用法: 讲source的属性值复制到target,属性为null时也会进行复制。 需求:排除null值进行复制 public class CopyObjectUtil { public static String...
  • Java如何复制对象

    万次阅读 多人点赞 2013-01-10 21:29:38
    假如说你想复制一个简单变量。很简单: int apples = 5; int pears = apples; ...不仅仅是int类型,其它七种...但是如果你复制的是一个对象,情况就有些复杂了。 假设说我是一个beginner,我会这样写: c
  • 需求:将对象属性值快速复制到另一个对象上,忽略空值属性和id 直接上代码:BeanUtils 工具类 import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import ...
  • java怎么复制一个一样的对象

    千次阅读 2018-06-24 22:08:32
    可以使用clone来实现,clone用于为引用类型的复制 1.使用clone方法的类必须先实现Cloneable接口,不然clone方法会直接返回CloneNotSupportedException不支持克隆的异常 实现Cloneable接口的类应该使用公共...
  • java 对象拷贝相同属性到另一个对象

    千次阅读 2020-11-28 16:54:43
    BeanUtils.copyProperties(对象1,要赋值的对象);
  • java对象拷贝效率对比----反射

    千次阅读 2018-08-16 17:11:09
    1.org.apache.commons.beanutils.BeanUtils属性拷贝的本质使用反射。...3.自己写的反射进行对象复制。 4.直接使用get、set方法复制。 5.cglib的BeanCopier。   次数 10 ...
  • Java克隆复制一个新的List集合的方法

    千次阅读 2021-02-12 10:01:58
    Java开发中,有时候我们为了源List集合的数据不被修改,如果...Java克隆复制ArrayList等List集合的方法一:Java中克隆复制一个List可以在创建List对象时通过将源List集合以参数的形式传入即可,代码如下:import...
  • @SneakyThrows public static Object objectClone(Object newObject,Object oldObject){ Field[] oldFields = oldObject.getClass().getDeclaredFields(); Field newField; for (Field ...
  • java 判断一个对象是否为空对象

    万次阅读 2020-03-30 22:29:29
    最近项目中遇到一个问题,在用户没填数据的时候,我们需要接收从前端传过来的对象为null,但是前端说他们一个一个判断特别麻烦,只能传个空对象过来,我第一个想法就是可以通过反射来判断对象是否为空。 第一版: ...
  • import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; public class CopyUtils { public static void Copy(Object source, Object dest) throws Exception { //...
  • BeanUtils.copyProperties map转对象也可,key与属性名相同即可
  • 引入包 import org.springframework.beans.BeanUtils; 调用copyProperties方法 BeanUtils.copyProperties(源对象, 目标对象);
  • JSONObject fys = new JSONObject(); fys.put("11","22"); JSONObject fys2 = JSONObject.parseObject(fys.toJSONString()); 将json对象转为字符串,将字符串重新构建 JSONObject
  • java个对象相同字段复制

    万次阅读 2019-01-24 09:42:19
    将user和userInfo拥有相同字段的值复制到userInfo对象中(如果user和userInfo间存在名称不相同的属性,则BeanUtils不对这些属性进行处理,需要手动处理) import org.springframework.beans.BeanUtils ...
  • 大家在日常的java开发中,经常会使用到对象之间属性的赋值操作,如果两个对象之间复制的属性不多的... 如何使用一句简单的代码直接复制上百个属性,这里介绍几种常用的方法,以及本人在实际项目中碰到的一个坑。 ...
  • java Map 复制对象复制

    万次阅读 2016-10-26 14:55:16
    b:深复制(深克隆):深复制把要复制对象所引用的对象复制遍。  序列化和反序列化 Serializable 序列化的对象要实现Serializable接口才能实现序列化。 序列化后,通过反序列化可以得到和当前...
  • 使用package org.springframework.beans;包下的BeanUtils.copyProperties(source, target);即可。 转自:https://blog.csdn.net/u011019141/article/details/80977951
  • Java复制对象与集合工具类

    千次阅读 2019-03-31 19:13:04
    项目中经常需要将某个对象的属性值复制给另一个对象,或者将一个集合复制到另一个集合。利用spring提供的BeanUtils,自己简单封装了一个工具类。 public class CopyUtils { /** * 复制集合 */ public static &...
  • 对象克隆(复制)假如说你想复制一个简单变量。很简单:int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。但是如果你...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 472,439
精华内容 188,975
关键字:

java复制一个对象

java 订阅