《Effective Java》读书笔记
一、引言
1.几条基本规则:(清晰性和简洁性最为重要)
模块的用户永远也不应该被模块的行为所迷惑(那样就不清晰了),模块要尽可能小,但又不能太小
代码应该被重用,而不是被拷贝
模块之间的依赖性应该尽可能的降到最小
错误应该尽早的被检测出来,最好是在编译时刻
PS.你不该盲目的遵从这些规则,但是,你应该只在偶尔的情况下,有了充分理由之后采取打破这些规则
学习编程艺术首先要学会基本的规则,然后才能知道什么时候可以打破这些规则
二、创建和销毁对象
第一条:考虑用静态工厂方法代替构造器。它有以下优势:
1)它有名称
2)不必再每次调用它的时候都创建一个新对象
3)它可以返回原类型的任何子类型的对象
4)在创建参数化类型实例的时候,它使代码变得更加简洁
缺点:
1)类如果不含共有的或者受保护的构造器,就不能被子类化(它鼓励程序复用而不是继承)
2)它与其他的静态方法实际上没有任何区别(API文档中无法明确表示出来,可以用惯用命名来弥补)
第二条:遇到多个构造器参数时要考虑用构建器。一般常用方法:
1)重叠构造器(telescoping constructor)
2) JavaBean模式
3)build构建器
PS.语法糖:NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbonydrate(27).build();
第三条:用私有构造器或者枚举类型强化Singleton属性
第四条:通过私有构造器强化不可实例化的能力
第五条:避免创建不必要的对象:
1)不要用String s = new String("xxxx");而应该用String s = "xxxxx";前者复用会创建大量实例,后者只会创建一个
2)不要使用Boolean(String);而应该用Boolwan.valueOf(String);对于同时提供了静态工厂方法和构造器的不可变类,通常用静态方法,避免创建不必要的对象
3)用long sum = 0L;而不要用Long sum = 0L;要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱
4)现代的JVM实现具有高度优化的垃圾回收器,其性能很容易就会超过轻量级对象池的性能,因此除非重量级对象(数据库连接),少用线程池。
第六条:消除过期的对象引用(主要是为了防范内存泄露):
1)栈里被弹出的元素,记得要清空引用
2)缓存用WeakHashMap来实现
3)注意监听器和其他回调,保存对象的弱引用,例如,只将他们保存成WeakHashMap
第七条:避免使用终结方法(finalizer)
原因:它不能及时执行,甚至根本就不保证它们会被执行
用处:充当安全网,或者是为了终止非关系的本地资源
用法:记得调用super.finalizer;要记得记录终结方法的非法方法;考虑使用终结方法守卫者
三、对于所有对象都通用的方法
第八条:覆盖equals时请遵守通用约定
1)自反性
2)对称性
3)传递性
4)一致性
ps.使用诀窍在P36
第九条:覆盖equals时总要覆盖hashCode
约定内容:
1) 如果两个对象相同,那么它们的hashCode值一定要相同。重写equals方法,一定要重写hashCode方法。
2) 如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。
PS.Hash算法原理:当Set接收一个元素时根据该对象的内存地址算出hashCode,看它属于哪一个区间,在这个区间里调用equeals方法。
第十条:始终要覆盖toString方法
第十一条:谨慎的覆盖clone
由于它有许多缺点,另一个实现对象拷贝的好办法是提供一个拷贝构造器或者拷贝工厂
第十二条:考虑实现Comparable接口
有些类具有内在的排序功能,但是与equals不一致。有些集合使用comparable而不是equals做同性测试。
四、类和接口
第十三条:使类的成员的可访问性最小化
封装:又被称为信息隐藏,是模块化的前提和保证
模块化的好处:
1)各个模块可以独立开发、测试、优化、使用、理解和修改
2)加快系统开发的速度,因为这些模块可以并行开发
3)减轻了维护的负担,程序员可以更快的理解模块,而且在调试的时候可以不影响其他维护的负担
4)虽然模块本身不会带来更好的性能,但是它可以帮助调节性能,通过分析知道哪些模块影响了性能
5)提高软件的可重用性,模块可以在其它系统中使用
6)模块可以降低系统风险,整个系统不可用,但是模块却有可能是可用的
第十四条:在公有类中使用访问方法而非公有域
变量应该用private定义而不是public的,只能用get/set方法取
但是如果这个类是包级私有(default)的,或者是内部类的话,则没有关系
第十五条:使可变性最小化
使类变为不可变的5条规则:
1)不要提供任何会修改对象状态的方法(也称为mutator)
2)保证类不会被扩展(使类成为final的,或者限制访问构造器)
3)使所有域都是final的
4)使所有域都是私有的
5)确保对于任何可变组件的互斥访问(如果能set则不能get对象的引用)
不可变的类(如复数类),被称作函数(functional)式的做法,相对的是过程(procedural)式的做法和命令(imperative)式的做法
不可变的类往往有一个可变配套类,来弥补它性能上的缺点(String->StringBuilder)
坚决不要为每个get方法编写一个相应的set方法,除非有很好的理由。不可变类有很多优点,唯一缺点是潜在的性能问题
第十六条:复合优先于继承:继承的功能非常强大,但是也存在诸多问题,因为它违背了封装原则。只有当子类和超类之间确实存在子类型关系时,使用继承才是恰当的。否则,可以使用复合来代替继承。
第十七条:要么为继承而设计,并提供文档说明,要么就禁止继承
第十八条:接口优于抽象类:除非演变的容易性比灵活性和功能性更为重要的时候
第十九条:接口只用于定义类型:常量接口模式是对接口的不良使用,应该使用工具类(utility class)
第二十条:类层次优于标签类:合理设计类,不要在一个类里塞太多东西,而应该使用抽象类之类的方法分层
第二十一条:用函数对象表示策略:函数指针的主要用途就是实现策略(Strategy)模式
第二十二条:优先考虑静态成员变量:四种不同的嵌套类及用法
五、泛型
第二十三条:请不要在新代码中使用原生态类型(关于List<?>,一般用于只读模式,因为不知道里面元素的类型,所以不能执行add方法,除非是null。常在方法中出现,限制方法乱add元素,出于安全性考虑。)
第二十四条:消除非受检警告:使用@SuppressWarnings("unchecked"),并添加注释,尽量加在行上而不要加在方法上。
第二十五条:列表优先于数组:优先使用泛型而不是数组来存数据,因为泛型是编译时检查类型,而数组是运行时检查,前者更安全。数组和泛型不要混合用。
第二十六条:优先考虑泛型
第二十七条:优先考虑泛型方法
第二十八条:利用有限制通配符来提升API的灵活性:PECS原则(P119)
第二十九条:优先考虑类型安全的异构容器
六、枚举和注解
第三十条:用enum代替int常量
第三十一条:用实例域代替序数
第三十二条:用EnumSet代替位域
第三十三条:用EnumMap代替序数索引
第三十四条:用接口模拟可伸缩的枚举
第三十五条:注释优于命名模式
第三十六条:坚持使用Override注解
第三十七条:用标记接口定义类型(标记注解和标记接口各有用处)
七、方法
第三十八条:检查参数的有效性
第三十九条:必要时进行保护性拷贝
第四十条:谨慎设计方法签名
第四十一条:慎用重载:重载的话,最好保证参数数目不一致,或者所有重载方法的行为一致。否则程序很容易误入重载方法。
第四十二条:慎用可变参数:3个以下的参数用重载
第四十三条:返回零长度数组或是集合,而不是null
第四十四条:为所有导出的API元素编写文档注释
八、通用程序设计
第四十五条:将局部变量的作用于最小化:
1.不要过早的声明变量,而应该在他第一次使用的地方声明
2.声明时应该初始化变量,除非是特殊情况(try块内)
3.for循环优先于while循环,因为有循环变量可以使用
4.使方法小而集中,也可以将局部变量的作用域最小化
第四十六条:for-each循环优于传统的for循环
第四十七条:了解和使用类库:程序员应该把时间花在应用程序上,而不是底层的细节上。不要重复造轮子
第四十八条:如果需要精度的答案,请避免使用float和double:应该使用BigDecimal处理小数,或者int和long处理整数
第四十九条:基本类型优先于装箱基本类型:当装箱基本类型和基本类型比较时,装箱基本类型会自动拆箱。如果null对象被自动拆箱,会报NullPointerException异常
第五十条:如果其他类型更合适,则尽量避免使用字符串:字符串经常被错误的用来代替基本类型、枚举类型和聚合类型等
第五十一条:当心字符串连接的性能
第五十二条:通过接口引用对象:优先使用接口,这样会更灵活更聪明
第五十三条:接口优于反射机制:应该仅仅使用反射机制来实例化对象,而访问对象时则使用编译时已知的某个接口或者超类
第五十四条:谨慎的使用本地方法
第五十五条:谨慎的进行优化:不要费力去编写快速的程序——应该努力编写好的程序,速度自然会随之而来
第五十六条:遵守普遍接受的命名惯例
九、异常
第五十七条:只针对异常的情况才使用异常:逻辑控制中,应该使用“状态测试方法”或“可识别的返回值”方法,而不是把异常用于控制流
第五十八条:对可恢复的情况使用受检异常,对编程错误使用运行时异常
第五十九条:避免不必要的使用受检的异常
第六十条:优先使用标准的异常
第六十一条:抛出与抽象对应的异常
第六十二条:每个方法抛出的异常都要有文档
第六十三条:在细节消息中包含能捕获失败的信息
第六十四条:努力使失败保持原子性
第六十五条:不要忽略异常
十、并发
第六十六条:同步访问共享的可变数据
第六十七条:避免过度同步
第六十八条:excutor和task优先于线程
第六十九条:并发工具优先于wait和notify
第七十条:线程安全性的文档化
第七十一条:慎用延迟初始化
第七十二条:不要依赖线程调度器:确保可运行线程的平均数量不明显的多于处理器的数量
第七十三条:避免使用线程组(thread group),已基本废弃,应该使用线程池executor
十一、序列化
第七十四条:谨慎的实现Serializable接口
第七十五条:考虑使用自定义的序列化形式
第七十六条:保护性的编写readObject方法
第七十七条:对于实例控制,枚举类型优先于readResolve
第七十八条:考虑用序列化代理代替序列化实例
《Effective Java》读书笔记的更多相关文章
- csapp读书笔记-并发编程
这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...
- CSAPP 读书笔记 - 2.31练习题
根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1) 属于第一种情况 sum = x ...
- CSAPP读书笔记--第八章 异常控制流
第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...
- CSAPP 并发编程读书笔记
CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...
- 读书笔记汇总 - SQL必知必会(第4版)
本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...
- 读书笔记--SQL必知必会18--视图
读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...
- 《C#本质论》读书笔记(18)多线程处理
.NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...
- C#温故知新:《C#图解教程》读书笔记系列
一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...
- C#刨根究底:《你必须知道的.NET》读书笔记系列
一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...
- Web高级征程:《大型网站技术架构》读书笔记系列
一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...
随机推荐
- careercup-中等难度 17.5
17.5 写一个函数来模拟游戏. 游戏规则如下: 4个槽,里面放4个球,球的颜色有4种,红(R ),黄(Y),绿(G),蓝(B).比如, 给出一个排列RGGB,表示第一个槽放红色球,第二和第三个槽放绿 ...
- Google实习面试归来
咱们寝室共有两个人收到面试通知,我和另一哥们G. 今天早上8:30起了个大早,洗漱完毕,简历复印完毕,就和G骑车到达了世贸中 心酒店那儿.真不愧是世贸中心啊,装修就是华丽,连看门的都是印 ...
- h5拖放-ff的bug
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Android之网络编程利用PHP操作MySql插入数据(四)
因为最近在更新我的项目,就想着把自己在项目中用到的一些的简单的与网络交互的方法总结一下,所以最近Android网络编程方面的博文会比较多一些,我尽量以最简单的方法给大家分享,让大家明白易懂.如果有什么 ...
- 圆满完成Web安全测试培训课程广州公开班!
圆满完成Web安全测试培训课程广州公开班! http://gdtesting.com/news.php?id=187 下期<Web安全测试最佳实践>公开课通知:8月9.10日地点:广州 课 ...
- (转)STL
C++容器类 C++中的容器类包括“顺序存储结构”和“关联存储结构”,前者包括vector,list,deque等:后者包括set,map,multiset,multimap等. 若需要存储的元素数在 ...
- oracle数据库不支持mysql中limit功能
oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum并不是用户添加的字段,而是oracle系统自动添加的. (1)使查询结果最多返回前10行 ...
- scala学习笔记:match表达式
写了一个超级长的表达式,估计不是最简洁的: scala> def foo(ch:Any)=ch match { case true=>"male";case false ...
- LaTeX Pdf to Word
用LaTeX写的文稿,生成的pdf,如果要改成word文档,如何是最合适的方式? 查了很多帖子,比较靠谱的一种方式是先将pdf转成rtf格式,再用word打开rtf文件.也有直接从tex文件直接转成d ...
- ASP.NET MVC模型绑定的6个建议(转载)
ASP.NET MVC模型绑定的6个建议 发表于2011-08-03 10:25| 来源博客园| 31 条评论| 作者冠军 validationasp.netmvc.netasp 摘要:ASP.NET ...