先看一个例子

User user1 = new User();
user1.setId("111");
Map<String, User> map1 = new HashMap<>();
map1.put("a", user1); Map<String, User> map2 = new HashMap<>();
map2.putAll(map1); User user2 = map2.get("a");
user2.setId("222"); System.out.println("user1 id:"+user1.getId());
System.out.println("user2 id:"+user2.getId());
user1 id:222
user2 id:222

可以看到改了map2里的对象,map1里的也跟着改了。

所谓浅复制:则是只复制对象的引用,两个引用仍然指向同一个对象,在内存中占用同一块内存。被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对象。

深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

注意:直接map2=map1或者map2=map1.clone(),这些都是浅复制,另外map没有实现Cloneable接口,不过hashmap实现了。

关于java里克隆的理解:Java中的Cloneable接口理解

如何实现深拷贝?

利用java的序列化和反序列化,具体参阅java序列化反序列化深入探究(转)

 User user1 = new User();
user1.setId("111");
HashMap<String, User> map1 = new HashMap<>();
map1.put("a", user1); HashMap<String, User> map2 = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("tempfile"));
11 oos.writeObject(map1);
12
13 ois = new ObjectInputStream(new FileInputStream("tempfile"));
14 map2 = (HashMap<String, User>) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} User user2 = map2.get("a");
user2.setId("222"); System.out.println("user1 id:"+user1.getId());
System.out.println("user2 id:"+user2.getId());
user1 id:111
user2 id:222

更多知识可以参阅:Java中的不可变类理解

java对象深复制、浅复制(深拷贝、浅拷贝)的理解的更多相关文章

  1. 简单理解php深复制浅复制问题

    其实接触深复制浅复制是通过学习c++了解到的,比如c++很好用的模板,php是不允许方法模板和类模板 一个简单的例子,如果不是很了解php 的取地址符&,可以去看下官方文档,php的& ...

  2. Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...

  3. Java 的 clone 方法 && 浅复制和深复制

    1 Java中对象的创建过程 java创建对象的方式有以下两种: (1)使用new操作符创建一个对象 (2)使用clone的方法复制一个对象,(在Java中,clone是Object类的protect ...

  4. java 及 Jquery中的深复制 浅复制

    发现问题:最近 遇到由于复制对象之后,改变复制后的新变量,原先被复制的对象居然会跟着变. EX:java中: //holidayConfig.getEnd_time()会随着sTime的改变而改变 s ...

  5. iOS 深复制&浅复制

        1.无论是深复制还是浅复制,被复制的对象类型是不变的.此对象类型具有什么功能就具有什么功能,不会因为自行修改了返回对象的指针类型而改变.   比如: 这里的str和str1的值和指针地址完全一 ...

  6. iOS开发之Copy & MutableCopy及深复制 & 浅复制

    1.使用copy或mutableCopy方法可以创建一个对象的副本. copy: (1)需要实现NSCoppying协议 (2)创建的是不可变副本(如NSString.NSArray.NSDictio ...

  7. C++类四个默认函数&深复制&浅复制

    学习C++语言的同学都知道,C++中类是有默认的几个函数的,主要是有四个函数: 四个函数 默认构造函数:A(void),无参构造函数 拷贝(复制)构造函数:A(const A&a).用一个对象 ...

  8. Python深复制浅复制or深拷贝浅拷贝

    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.(比深拷贝更加节省内存)2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >& ...

  9. Java对象之间的深度复制拷贝

    /* * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETA ...

随机推荐

  1. 如何将sqlserver的windows验证模式改为SQL Server 和 Windows 混合身份验证模式

    今天问同事拷贝了份虚拟机,里面已装好sqlserver2008,可是他装的时候选择的是windows身份验证,我需要将其改成SQL Server 和 Windows 混合身份验证模式,具体步骤如下: ...

  2. MulticastSocket 使用

    /** * ServerMulticastSocketTest.java * 版权所有(C) 2014 * 创建者:cuiran 2014-1-9 下午3:22:01 */ package com.u ...

  3. eclipse 设置maven来自动下载源码与doc

    通常我们通过maven来使用各种库文件,想要真正了解别人的类实现方法,需要查看别人的源码,maven给我们提供了这个便利,它不仅可以下载各种库文件,还会下载对应的源码和doc文档. 一.在工具栏找到W ...

  4. shell-like program(shell程序的基本实施部分)

    直接上代码: #include "apue.h" #include <sys/wait.h> int main(void) { char buf[MAXLINE]; / ...

  5. 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解

    最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...

  6. Leetcode_217_Contains Duplicate

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/46271159 Given an array of inte ...

  7. OpenGL OpenCV根据视差图重建三维信息

    代码如下: // disparity_to_3d_reconstruction.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" //Huan ...

  8. 【45】java的封装剖析

    类是构造对象的模板或蓝图. 封装的一些概念 从形式上看,封装不过是将数据和行为组合到一个包中,并对对象的使用者隐藏了数据的实现形式. 每个对象都包含实例域和方法.实例域的集合代表了一个集合的状态,通过 ...

  9. 使用IO映射的方式获取tiny4412板子上的ID号

    在以前的文章中,有一篇 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号 在那篇文章中,具体可以参考.那时候我使用了简单的字符设备驱动框架,最终的ID号通过read方法可将 ...

  10. LeetCode(30)-Pascal's Triangle

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...