Item 11 谨慎地覆盖Clone】的更多相关文章

1.进行浅拷贝时,只是复制原始数据类型的值,则可以通过覆盖Clone方法来达到.另外,在进行浅拷贝的时候,还要注意,成员对象中不应该要有引用类型,如果有引用类型,那么,进行了浅拷贝之后,两个对象将会共享成员引用所指向的对象,这会出现问题.所以,在这种情况下,干脆直接使用深拷贝,避免问题出现.2.对于深拷贝,也就是完全将对象的内容复制一份,则使用序列化来实现,也是为了避免覆盖Clone.   浅拷贝的例子: 这个例子,只是复制成员的值,成员的类型都是原始数据类型,不包含引用类型: public c…
Clone提供一种语言之外的机制:无需调用构造器就可以创建对象. 它的通用约定非常弱: 创建和返回该对象的一个拷贝.这个拷贝的精确含义取决于该对象的类.一般含义是,对于任何对象x,表达式x.clone() != x 将会是true,并且,表达式x.clone().getClass() == x.getClass() 将会是true,但这些不是绝对的要求,通常情况下,表达式 x.clone().equals(x) 将会是true,这也不是一个绝对的要求,拷贝对象往往是创建它的类的一个新实例,但它同…
1.概述 如果clone方法返回一个由构造器创建的对象,它就得到有错误的类.因此,如果覆盖了非final类中的clone方法,则应该返回一个通过调用super.clone得到的对象.如果类的所有超类都遵循这条规则,那么调用super.clone最终会调用Object的clone方法,从而创建出正确的实例.这种机制类似于自动的构造器调用链,只不过它不是强制要求的. 2.示例 需求: 为HashTable编写一个clone方法,它内部数据包含一个HashTable数组,每个HashTable都指向键…
一个类要想实现克隆,需要实现Cloneable接口,表明这个类的对象具有克隆的功能. Cloneable接口是一个mixin接口,它里面并没有任何的抽象方法,类似的接口有Serializable接口,表明该类的对象可以序列化. 首先应该明确通过一个对象克隆出另一个对象的概念:通过一个对象克隆出另一个对象,简称对象1和对象2,这两个对象就成为两个独立的对象, 那么对对象1做任何的修改,对象2应该不受影响:对对象2做任何的修改的,对象1就不应该受影响.这样就要求对象1与对象2的实例域各自是独立的.…
覆盖clone时需要实现Cloneable接口,Cloneable并没有定义任何方法. 那Cloneable的意义是什么? 如果一个类实现了Clonable,Object的clone方法就可以返回该对象的逐域拷贝,否则会抛出CloneNotSupportedException. 通常,实现接口是为了表明类的行为. 而Cloneable接口改变了超类中protected方法的行为. 这是种非典型用法,不值得仿效. 好了,既然覆盖了clone方法,我们需要遵守一些约定: x.clone() != x…
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 13. 谨慎地重写 clone 方法 Cloneable接口的目的是作为一个mixin接口(条目 20),公布这样的类允许克隆.不幸的是,它没有达到这个目的.它的主要缺点是…
本文参考 本篇文章参考自<Effective Java>第三版第十三条"Always override toString",在<阿里巴巴Java开发手册>中也有对clone方法规约: [推荐]慎用 Object的 clone方法来拷贝对象.  说明:对象clone 方法默认是浅拷贝,若想实现深拷贝需覆写clone 方法实现域对象的深度遍历式拷贝. 关于深拷贝和浅拷贝的见解,还可以参考此文章:https://www.jianshu.com/p/94dbef2de2…
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果你为其他开发者提供代码,并且你想阻止他们调用一个特定的函数,你通常不会声明这个函数.函数不声明,函数就不会被调用.太简单了!但是有时候C++会帮你声明函数,并且如果你想要阻止客户调用这些函数,简单的事情就不再简单了. 这种情况只发生在"特殊的成员函数"身上,也就是,当你需要这些成员函数的时候,C++会自动帮你生成.Item 17详细地讨论了这些函数,…
unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls; type   TForm1 = class(TForm)     Button1: TButton;     Button2: TButton;     Button3: TButton;     procedure Button1Click(Sen…
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to self. 这看上去是愚蠢的,但这是合法的,所以请放心,客户端是可以这么做的.此外,自身赋值也并不总是很容易的能够被辨别出来.举个例子: a[i] = a[j]; // potential assignment to self 上面的代码在i和j相等的情况下就是自我赋值,同样的,看下面的例子: *px =…
重载.覆盖.隐藏 重载 在同一类定义的成员函数中,参数不同的同名函数为重载关系.重载与虚函数无关. class A{ private: int x; public: void fun(int); //重载关系的三个函数, void fun(double,double); virtual fun(); }; 覆盖 派生类的成员函数覆盖了基类中的同名函数.参数相同且基类中的同名函数为虚函数时会覆盖. class L{ //基类 private: int x; public: virtual void…
题目:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 在分析前不知道是什么序列,所以先看了n=1,n=2,n=3,n=4的情况摸索规律,主要是看 n 和 n-1 的隐含联系.(2*1 指 长宽) 结论:f(n) = f(n-1)+f(n-2)   (n>=3) public class Solution { public int RectCover(int target) { if(target == 0){ re…
代码应该被重用,而不是被拷贝 同大多数学科一样,学习编程的艺术首先要学会基本的规则,然后才能知道什么时候可以打破这些规则   创建和销毁对象 1.考虑用静态工厂方法代替构造器. 优势:有名称.不必再每次调用他们的时候都创建一个对象.可以返回原类型的任何子类型的对象.代码变得更简洁 //抽象产品角色 public interface Car { public void drive(); } //具体产品角色 public class Benz implements Car { public voi…
第3章 对于所有对都通用的方法 尽管Object是一个具体类,但是设计它主要是为了扩展,它所有的非final方法(equals,hashCode,toString,clone和finalize)都有明确的通用约定,因为它们被设计成是要被覆盖的.任何一个类,它在覆盖这些方法的时候,都有责任遵守这些通用约定.如果不能做到这一点,其他依赖于这些约定的类(如HashMap和HashSet)就无法结合该类一起正常工作. 8. 覆盖equals时请遵守通用约定 如果累具有自己特有的“逻辑相等”概念(不同于对…
1.考虑用静态工厂方法代替构造器 public static Boolean valueOf(boolean b){ return b?Boolean.TRUE:Boolean.FALSE; } 静态工厂方法与构造器不同的第一大优势在于,它们有名称,有名称可以更好地构建清晰的对象. 静态工厂方法与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新对象,实例受控的类. 静态工厂方法与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象,API可以返回对象,同时又不会使…
综述 Object是Java中所有类的父类,对它的学习十分的重要, Object的函数除了final方法,基本上都是被设计为要被覆盖的(Override),这节我们就一起来学习这些函数. 1.equals函数 /*equals的源代码*/public boolean equals(Object obj) { return (this == obj); } 从源代码中我们可以看出来,不重写equals函数的话,一个对象只会与它本身相等,因此对于"值类"(String.Integer等)我…
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4255581.html 第三章      对所有对象都通用的方法 8.            覆盖equals时请遵守通用约定 如果类具有自己特定的"逻辑相等"概念(不同于对象等同概念)…
Object类的所有非final方法(equals.hashCode.toString.clone.finalize)都要遵守通用约定(general contract),否则其它依赖于这些约定的类(HashMap,HashSet等)将不能正常工作. 8.覆盖equals时请遵守通用约定 无需覆盖equals的情形: 类的每个实例本质上是唯一的.类代表的是活动实体而不是值的概念.(例如,类Thread) 不关心类"逻辑相等"的功能,从Object继承的equals实现已经足够.(例如,…
创建和销毁对象 1.考虑用静态工厂方法(返回类的实例的静态方法)代替构造器2.遇到多个构造器参数时要考虑用构造器3.用私有构造器或者枚举类型强化Singleton属性4.通过私有构造器强化不可实例化的能力5.避免创建不必要的对象6.消除过期的对象引用7.避免使用终结(final)方法 对于所有对象都通用的方法 8.覆盖equals时请遵守通用约定9.覆盖equals时总要覆盖hashCode10.始终要覆盖toString11.谨慎地覆盖clone12.考虑实现Comparable接口 类和接口…
目录: 一.创建和销毁对象 (1 ~ 7) 二.对于所有对象都通用的方法 (8 ~ 12) 三.类和接口 (13 ~ 22) 四.泛型 (23 ~ 29) 五.枚举和注解 (30 ~ 37) 六.方法 (38 ~ 44) 七.通用程序设计 (45 ~ 56) 八.异常 (57 ~ 65) 九.并发 (66 ~ 73) 十.序列化 (74 ~ 78)   正文:   第一章: 创建和销毁对象 1.考虑用静态工厂方法代替构造器 优: ① 有名称 ② 不必在每次调用它们的时候都创建一个对象 ③ 可以放…
第10条:始终要覆盖toString 这一条没什么好讲的,就是说默认的toString方法打印出来的是类名+@+十六进制哈希码的值.我们应该覆盖它,使它能够展示出一些更为详细清晰的信息,这个看实际情况吧. 第11条:谨慎地覆盖clone 有时候会出现这样的场景,你需要备份一些数据,对其一进行修改时,另外一个不受影响.这样,直接Foo a = new Foo(); Foo b = a; 是不可行的,b引用和a指向的是同一个对象. 这一条讲了很多,最后的总结是,Cloneable接口坑很多,因此最好…
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约会持续1个月左右. 第1条:考虑用静态工厂方法代替构造器 通常情况下我们会利用类的构造器对其进行实例化,这似乎毫无疑问.但“静态工厂方法”也需要引起我们的高度注意. 什么是“静态工厂方法”?这不同于设计模式中的工厂方法,我们可以理解它为“在一个类中用一个静态方法来返回这个类的实例”,例如: public st…
<Effective Java(中文第二版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382186 Java(中文第二版)>[PDF]"  TITLE="<Effective Java(中文第二版)>[PDF]" /> 编辑推荐 <Sun 公司核心技术丛书:EffectiveJava中文版(第2版)>内容全面,结构清晰,讲解详细.可作为技术人员的参考用书.编码平添乐…
第二章——创建和销毁对象 第1条:考虑用静态工厂方法替代构造器 第2条:遇到多个构造器参数时要考虑用构建器 第3条:用私有构造器或者枚举类型强化Singleton属性 第4条:通过私有构造器强化不可实例化的能力 第5条:避免创建不必要的对象 第6条:消除过期的对象引用 第7条:避免使用终结方法 第三章——对于所有对象都通用的方法 第8条:覆盖equals时请遵守通用约定 第9条:覆盖equals时总要覆盖hashCode 第10条:始终要覆盖toString 第11条:谨慎地覆盖clone 第1…
说明 这里是阅读<Effective Java中文版第二版>的读书笔记,这里会记录一些个人感觉稍微有些重要的内容,方便以后查阅,可能会因为个人实力原因导致理解有误,若有发现欢迎指出.一些个人还不理解的会用斜线标注. 第一章是引言,所以跳过. 第二章 创建和销毁对象 第1条:考虑用静态工厂方法代替构造器 含义 静态工厂方法是指一个返回类的实例的静态方法,例如: public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE :…
第8条: 覆盖equals时请遵守通用约定 我们在覆盖equals方法时,必须遵守它的通用约定: 1.自反性.对于任何非null的引用值x,x.equals(x)必须返回true: 2.对称性.对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true: 一个“不区分大小写”字符串的例子: public class CaseInsensitiveString { private final String s; public CaseIn…
Cloneable接口的目的是作为对象的一个mixin接口,表明这样的对象允许克隆.如果一个类实现了Cloneable接口,Object的clone方法就返回该对象的逐域拷贝,相当于无需调用构造器就可以创建对象. 克隆复杂对象的方法是:先调用super.clone(),然后通过类中的final方法来重新设置对象的属性. 参考资料 <Effective Java 中文版 第2版> 第11条:谨慎地覆盖clone P46-52…
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约会持续1个月左右. 第1条:考虑用静态工厂方法代替构造器 通常情况下我们会利用类的构造器对其进行实例化,这似乎毫无疑问.但“静态工厂方法”也需要引起我们的高度注意. 什么是“静态工厂方法”?这不同于设计模式中的工厂方法,我们可以理解它为“在一个类中用一个静态方法来返回这个类的实例”,例如: public st…
第1章 引言 第2章 创建和销毁对象 第1条:考虑用静态工厂方法代替构造器(Consider static factory methods instead of constructors) 第2条:遇到多个构造器参数时要考虑用构建器(Consider a builder when faced with many constructor parameters ) 第3条:用私有构造器或者枚举类型强化Singleton属性( Enforce the singleton property with a…
推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象 第1项:用静态工厂方法代替构造器 第2项:遇到多个构造器参数时要考虑使用构建器 第3项:用私有构造器或者枚举类型强化Singleton属性 第4项:通过私有构造器强化不可实例化的能力 第5项:优先考虑依赖注入来引用资源 第6项:避免创建不必要的对象 第7项:消除过期的对象引用 第8项:避免使用终结方法和清除方法 第9项:try-with-resources优先于try-finally 第三章 对于所有对象都通用的方法 第10项:覆盖equ…