老是会遇到深拷贝与浅拷贝的问题,这里进行了一些測试。代码例如以下:

</pre><pre name="code" class="java">/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*; /**
*
* @author User
*/ class Weiz implements Serializable{//对象序列化。要实现这个接口
private static final long serialVersionUID=123L;//序列化版本号
double x;
public Weiz(double a){
x=a;
}
} public class test_copy { /**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO code application logic here
List<Weiz> lst=new ArrayList();
lst.add(new Weiz(1.1));
lst.add(new Weiz(1.2));
lst.add(new Weiz(1.3));
System.out.println("复制前。原始lst:");
for(int i=0;i<lst.size();++i){
System.out.println(lst.get(i)+" "+lst.get(i).x);
}
//System.out.println();
//构造函数复制 浅拷贝
List<Weiz> lst2=new ArrayList(lst);
//lst2.set(1, new Weiz(2.1));
lst2.get(0).x=2.1;
System.out.println("构造函数复制且改动后。新的lst2:");
for(int i=0;i<lst2.size();++i){
System.out.println(lst2.get(i)+" "+lst2.get(i).x);
}
System.out.println("构造函数复制且改动后,原始lst:");
for(int i=0;i<lst.size();++i){
System.out.println(lst.get(i)+" "+lst.get(i).x);
} List<Weiz> lst3=deepCopy(lst);
lst3.get(0).x=3.1;
System.out.println("对象序列化复制且改动后,新的lst3:");
for(int i=0;i<lst3.size();++i){
System.out.println(lst3.get(i)+" "+lst3.get(i).x);
}
System.out.println("对象序列化复制且改动后,原始lst:");
for(int i=0;i<lst.size();++i){
System.out.println(lst.get(i)+" "+lst.get(i).x);
} List<Weiz> lst4=deepCopy(lst);
lst4.get(0).x=4.1;
System.out.println("对象序列化复制且改动后。新的lst4:");
for(int i=0;i<lst4.size();++i){
System.out.println(lst4.get(i)+" "+lst4.get(i).x);
}
System.out.println("对象序列化复制且改动后。原始lst:");
for(int i=0;i<lst.size();++i){
System.out.println(lst.get(i)+" "+lst.get(i).x);
}
} //关键代码 运行序列化和反序列化 进行深度拷贝
public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
} //关键代码 运行序列化和反序列化 进行深度拷贝,写法不同而已,作用一样
//个人习惯 怎么喜欢怎么来!
public List deepCopy2(List src) throws IOException, ClassNotFoundException{
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in =new ObjectInputStream(byteIn);
List dest = (List)in.readObject();
return dest;
}
}
<pre name="code" class="plain">程序结果:
run:
复制前:
readdxflunwen.Weiz@c17164 1.1
readdxflunwen.Weiz@1fb8ee3 1.2
readdxflunwen.Weiz@61de33 1.3
构造函数复制且改动后,新的lst2:
readdxflunwen.Weiz@c17164 2.1
readdxflunwen.Weiz@1fb8ee3 1.2
readdxflunwen.Weiz@61de33 1.3
构造函数复制且改动后,原始lst:
readdxflunwen.Weiz@c17164 2.1
readdxflunwen.Weiz@1fb8ee3 1.2
readdxflunwen.Weiz@61de33 1.3
对象序列化复制且改动后。新的lst3:
readdxflunwen.Weiz@60aeb0 3.1
readdxflunwen.Weiz@16caf43 1.2
readdxflunwen.Weiz@66848c 1.3
对象序列化复制且改动后,原始lst:
readdxflunwen.Weiz@c17164 2.1
readdxflunwen.Weiz@1fb8ee3 1.2
readdxflunwen.Weiz@61de33 1.3
对象序列化复制且改动后,新的lst4:
readdxflunwen.Weiz@8813f2 4.1
readdxflunwen.Weiz@1d58aae 1.2
readdxflunwen.Weiz@83cc67 1.3
对象序列化复制且改动后。原始lst:
readdxflunwen.Weiz@c17164 2.1
readdxflunwen.Weiz@1fb8ee3 1.2
readdxflunwen.Weiz@61de33 1.3
成功构建 (总时间: 4 秒)

能够看到。用构造函数(旧List)的方法。是浅拷贝,拷贝的仅仅是List中的元素,即引用,而不是这些元素或引用指向的值。

而通过对象序列化方法,则是深拷贝,是把这些引用指向的对象又一次创建了一份的。

从打印的结果也能够看到。浅拷贝时,新list中元素的值和旧List是一样,即引用是一样的。而深拷贝时,新List中元素的值和旧List的是不一样的。即引用值是不一样的。你想一下。深拷贝是又一次创建了一份指向的对象。那么指向这个新对象的引用值当然和旧的应该是不一样的!

对象序列化方法是參考别的文章。链接Here

当类实现了Serializable 接口,它的对象才是可序列化的。

实际上,Serializable 是一个空接口,它的目的仅仅是标识一个类的对象能够被序列化。

可序列化类中的属性serialVersionUID用于标识类的序列化版本号,若不显示定义该属性,JVM会依据类的相关信息计算它的值,而类改动后的计算结果与改动前的计算结果往往不同,这样反序列化时就会因版本号不兼容而失败。

假设一个类是可序列化的。则它的全部子类也是可序列化的。当序列化对象时,假设对象的属性又引用其它对象。则被引用的对象也必须是可序列化的。

Java List 的深拷贝的更多相关文章

  1. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  2. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  3. 内功心法 -- Java中的深拷贝和浅拷贝

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...

  4. 浅析Java中的深拷贝和浅拷

      浅析Java中的深拷贝和浅拷贝 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: in ...

  5. Java 浅拷贝、深拷贝,你知多少?

    这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...

  6. 2种方法实现java对象的深拷贝

    2种方法实现java对象的深拷贝 2017年12月03日 22:23:07 iCoding91 阅读数 4420更多 分类专栏: java   版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...

  7. Java中的深拷贝和浅拷贝

    1.浅拷贝与深拷贝概念 (1)浅拷贝(浅克隆) 浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源 ...

  8. Java 浅拷贝和深拷贝的理解和实现方式

    Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...

  9. java克隆之深拷贝与浅拷贝

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java深拷贝与浅拷贝实际项目中用的不多,但是对于理解Java中值传递,引用传递十分重要,同时个人认为对于理解内存模型也有帮助,况且面试中也是经常问 ...

  10. JAVA如何实现深拷贝

    protected 域(或方法)微妙的规则 protected 域(或方法)对本包内的所有类可见(当然包括子类),那么,子类可以获得访超类受保护域(或方法)的权利,但是,若子类和超类不在同一个包下,就 ...

随机推荐

  1. 为什么我们使用Nginx而不是Apache?

    我们大多数的客户在他们的服务器上使用Apache作为Web服务器,尤其是部署在一个基于PHP系统的前端并且使用mod-PHP.鉴于扩张性和性能方面的原因,我们通常会建议他们改用Nginx和FPM. A ...

  2. PHP中文手册2

    11.异常处理 用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理类.以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的.译者注:以下这段代码只为说明内置异常处理类 ...

  3. Cmder 简明使用说明

    简介 Cmder is a software package created out of pure frustration over the absence of nice console emul ...

  4. Emgu CV 初试

    Emgu CV 是.NET平台下对OpenCV图像处理库的封装,也就是.NET版.可以运行在C#.VB.VC++等. 安装完成后需要设置环境变量,比如我安装在D:\Emgu\emgucv-window ...

  5. 学习笔记:MDN的服务器端网站编程

    互联网是如何工作的 互联网(Internet)和网络(web) 互联网是基础设施,网络是建立在这种基础设施之上的服务. 网页,网站,网络服务器和搜索引擎的区别是什么? 网页(webpage) 一份能够 ...

  6. wow.js+animate.css——有趣的页面滚动动画

    今天偶然间发现了一个使用特别简单的页面动画效果,还挺不错的,玩了一个上午,现在介绍一下这个滚动动画: 一.使用方法: 1.下载animate.css 2.下载wow.js 3.引用文件,像这样: &l ...

  7. pm2部署node应用

    背景: 很早就知道了pm2的强大功能,部署,多进程部署,负载均衡等等,但是一直没有取尝试使用,每次写完代码就没关心部署的事了.最近有空就想着把pm2的部署流程走一遍,顺便整理出来. 环境: 1.本地: ...

  8. JavaScript基础:(加号,数值转换,布尔转换)

    JavaScript中加号运算符"+" 运算过程理解 1) 如果其中一个操作数是对象,则对象会遵循对象到原始值的转换规则转换为原始值.日期对象通过toString()方法执行转换, ...

  9. C#之MVC3继续整理问题

    1.注释验证[EmailAddress(ErrorMessage = "×")],用的MVC3框架,此处报错,找不到类“EmailAddress”,看到原文有using Syste ...

  10. php使用GD库实现图片水印和缩略图——生成图片缩略图

    今天呢,就来学习一下在php中使用PD库来实现对图片水印的文字水印方法,不需要PS哦! 首先,准备素材 (1)准备一张图片 (2)准备一张水印(最好是透明的,即背景是白色底) (3)准备一中字体(在电 ...