JAVA如何实现深拷贝
protected 域(或方法)微妙的规则
protected 域(或方法)对本包内的所有类可见(当然包括子类),那么,子类可以获得访超类受保护域(或方法)的权利,但是,若子类和超类不在同一个包下,就不能访问超类对象的这个受保护域(或方法)。也就是说,不在一个包下,子类中不能通过一个父类对象的引用来获得父类受保护的域(或方法),测试如下。
package protect2;
public class P{
protected int a;
public P(){}
public P(int a){
this.a = a;
}
protected void fun(){
System.out.println("父类protected方法");
}
}
package protect2;
public class ProtectedTest {
public String s;
public ProtectedTest(String s) {
this.s = s;
}
P ap = new P(10);
void foo() {
ap.fun();
System.out.println("ap.a " + ap.a);
}
public static void main(String[] args) {
ProtectedTest test = new ProtectedTest("abcdef");
test.foo();
System.out.println(test.s);
}
}
package protect;
import protect2.P;
class C extends P{
public int b;
public C(int a,int b){
super(a);
this.b = b;
}
public void afun(){
P pp = new P(10);
System.out.println("C.a= " + a);
System.out.println("P.a= " + pp.a);//ERROR:The field P.a is not visible
pp.fun(); //ERROR:The method fun() from the type P is not visible
}
浅拷贝与深拷贝
Object类对自己的具体子类的域一无所知,Object类的clone方法只是将各个域进行拷贝。数值或基本类型不会出现问题,但是,如果在对象中包含了引用对象,这些对象的内容没有被自我复制,拷贝的结果也即是原始对象和拷贝对象引用着同一个引用对象(一般地,动词“引用”可理解为“管理”,就是指向同一内存)。
浅拷贝满足:
x.clone() != x为true,x.clone().getClass() == x.getClass()为true,((x.clone().field1 ) == (x. field1))&& … &&((x.clone().fieldN )==(x. fieldN))也为true。
如果原始对象与浅拷贝对象共同引用(管理、指向)的引用对象是不可变的,将不会产生任何问题,如,引用对象是String类对象;或引用对象在其生命周期不会发生变化,具体来说,管理它的类中没有更改它的方法,也没有返回对它引用的方法(分享其管理权的方法)。
如果原始对象管理的引用对象是可变的,就必须需重新定义clone方法,来实现深层次的拷贝。要对涉及的每一个类,判断以下两点:
- 默认的clone方法是否满足需求。
- 默认的clone方法是否能通过调用可变引用对象的clone方法得到解决。
对涉及的每一个类,深拷贝要满足:
x.clone() != x为true,x.clone().getClass() == x.getClass()为true,x.clone().equals(x)也为true,当然equals方法是如此重写过的。
Object类中的clone方法被声明为protected,防止出现文章开头所提到的,子类和超类不在同一个包下的情况,要声明clone为public,来实现深拷贝:
import java.util.Date;
public class EqualsT {
public static void main(String[] args) throws CloneNotSupportedException {
Date hireDay = new Date();
Employee e1 = new Employee("Tommy", 10, "9998", hireDay);
Employee e2 = new Employee("Tommy", 10, "9998", hireDay);
System.out.println(e1.equals(e2));
System.out.println(e1 == e2);
Employee e3 = (Employee) e1.clone();
System.out.println(e1.equals(e3));
}
}
//Cloneable为标记接口,接口内没有方法。
class Employee implements Cloneable {
String name;
int age;
String salary;
Date hireDay;
public Employee(String name, int age, String salary, Date hireDay) {
super();
this.name = name;
this.age = age;
this.salary = salary;
this.hireDay = hireDay;
}
@Override
public boolean equals(Object otherObject) {
if (this == otherObject)
return true;
if (otherObject == null)
return false;
if (!(otherObject instanceof Employee))
return false;
Employee other = (Employee) otherObject;
return name.equals(other.name) && age == other.age && salary.equals(other.salary)
&& hireDay.equals(other.hireDay);
}
@Override
protected Object clone() throws CloneNotSupportedException {
// call Object.clone()
Employee cloned = (Employee) super.clone();
// call mutable fields
cloned.hireDay = (Date) hireDay.clone();
return cloned;
}
}
Output:
true
false
true
// JDK中Date类的克隆方法
public Object clone() {
Date d = null;
try {
d = (Date)super.clone();
if (cdate != null) {
d.cdate = (BaseCalendar.Date) cdate.clone();
}
} catch (CloneNotSupportedException e) {} // Won't happen
return d;
}
——@guoyangde http://www.cnblogs.com/LittleTreasureBox/p/8904016.html
JAVA如何实现深拷贝的更多相关文章
- 浅谈Java中的深拷贝和浅拷贝(转载)
浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...
- 浅谈Java中的深拷贝和浅拷贝
转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...
- 内功心法 -- Java中的深拷贝和浅拷贝
写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...
- 浅析Java中的深拷贝和浅拷
浅析Java中的深拷贝和浅拷贝 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: in ...
- Java 浅拷贝、深拷贝,你知多少?
这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...
- 2种方法实现java对象的深拷贝
2种方法实现java对象的深拷贝 2017年12月03日 22:23:07 iCoding91 阅读数 4420更多 分类专栏: java 版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...
- Java中的深拷贝和浅拷贝
1.浅拷贝与深拷贝概念 (1)浅拷贝(浅克隆) 浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源 ...
- Java 浅拷贝和深拷贝的理解和实现方式
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...
- java克隆之深拷贝与浅拷贝
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java深拷贝与浅拷贝实际项目中用的不多,但是对于理解Java中值传递,引用传递十分重要,同时个人认为对于理解内存模型也有帮助,况且面试中也是经常问 ...
随机推荐
- Redis 慢日志
redis的slowlog是redis用于记录记录慢查询执行时间的日志系统.由于slowlog只保存在内存中,因此slowlog的效率很高,完全不用担心会影响到redis的性能.Slowlog是Red ...
- 【Python】 高级文件操作 shutil
shutil 很多时候,我想要对文件进行重命名,删除,创建等操作的时候的想法就是用subprocess开一个子进程来处理,但是实际上shutil可以更加方便地提供os的文件操作接口,从而可以一条语句搞 ...
- fail2ban 防止ssh暴力破解
1.环境 CentOS 7 2.在线安装 yum install -y epel-release yum install -y fail2ban fail2ban 结构 /etc/fail2ban ...
- 键值编码KVC
动态设置:setValue:属性值 forKey:属性名用于简单路径:setValue:属性值 forKeyPath:属性路径用于复合路径,例如Person有一个Account类型的属性,那么pers ...
- unittest自动化使用HTMLTestRunner的中文编码问题
1.使用unittest自动化测试框架,使用HTMLTestRunner生成测试报告,中文乱码问题! 如图 2.解决方法: 第一步:先在自己的测试脚本中添加 import sys reload(sys ...
- 集大1513 & 1514班 软件工程第二次作业评分与点评
谢谢按时完成作业的同学. 请大家在今后的作业中多思考,认真完成并注意作业的原创性. 学号 作业标题 作业地址 提交日期 分数 201521121087 微信APP简要分析 http://www.cnb ...
- Beta冲刺第五天
一.昨天的困难 没有困难. 二.今天进度 1.林洋洋:日程刷新重构. 2.黄腾达:创建协作日程当选择只触发一次时自动填充1,并禁用input. 3.张合胜:修复列表显示日程重复单位的格式化. 三.明日 ...
- 201621123050 《Java程序设计》第1周学习总结
1.本周学习总结 java历史概述 java特点:1.简单 2.面向对象 3.健壮 4.跨平台 5.类库众多 JDK.JRE.JVM JDK:JAVA 开发工具包 ,包含JRE JRE: JAVA运行 ...
- 201621123068 Week04-面向对象设计与继承
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:继承.多态.重载.关键字.父类与子类 1.2 尝试使用思维导图将这些关键词组织起来. 2. 书面作业 1. 面向对象设计(大 ...
- Linux下vim上编辑实现进度条
1.效果展示: 进度条,先来看一个效果: 这是进度结果,模拟实现了进度条的前进.百分比的现实.以及稍微的动画特效. 2.原理描述: 因为Linux系统下的输出有缓存,如果及时刷新显示,就可以得到我们想 ...