目录:
一、创建和销毁对象 (1 ~ 7)
二、对于所有对象都通用的方法 (8 ~ 12)
三、类和接口 (13 ~ 22)
四、泛型 (23 ~ 29)
五、枚举和注解 (30 ~ 37)
六、方法 (38 ~ 44)
七、通用程序设计 (45 ~ 56)
八、异常 (57 ~ 65)
九、并发 (66 ~ 73)
十、序列化 (74 ~ 78)
正文:
第一章: 创建和销毁对象
1、考虑用静态工厂方法代替构造器
优:
① 有名称
② 不必在每次调用它们的时候都创建一个对象
③ 可以放回原返回类型的任何子类型的对象
④ 在创建参数化类型实例的时候,代码更简洁
缺:
① 类如果不含公有的或受保护的构造器,就不能被子类化
② 与其他一般的静态方法无多大区别
2、 遇到多个构造器参数时要考虑用构造器
3、用私有构造器或者枚举类型强化 Singleton 属性
4、通过私有构造器强化不可实例化的能力
5、避免创建不必要的对象
6、消除过期的对象引用
7、避免使用终结方法
第二章: 对于所有对象都通用的方法
8、覆盖 equals 时请遵守通用约定
① 类的每个实例本质上是唯一的
② 不关心类是否提供了“逻辑相等”的测试功能
③ 超类已经覆盖了 equals, 从超类继承过来的行为对于子类也是合适的
④ 类是私有的或包级私有的,可以确定它的 equals 方法永远不会被调用
实现高质量 equals 方法诀窍:
① 使用 “==”操作符检查“参数是否为这个对象的引用”
② 使用 instanceof 操作符检查“参数是否为正确的类型”
③ 把参数转换为正确的类型
④ 对于该类中的每个“关键”域,检查参数中的域是否参与该对象中的对应的域相匹配
⑤ 当你编写完成了 equals 方法之后,应该判断其是否满足了 对称性、传递性、一致性
- 覆盖 equals 时总要覆盖 hashCode
- 不要企图让 equals 方法过于智能
- 不要将 equals 声明中的 Object 对象器替换为其他的类型
9、覆盖 equals 时总要覆盖 hashCode
10、始终要覆盖 toString
11、谨慎地覆盖 clone
12、考虑实现 Comparable 接口
第三章:类和接口
13、使类和成员的可访问性最小化
14、在公有类中使用访问方法而非公有域
15、使可变性最小化
① 不要提供任何会修改对象状态的方法
② 保证类不会被扩展
③ 使所有的域都是 final 的
④ 使所有的域都成为私有的
⑤ 确保对于任何可变组件的互斥访问
16、复合优先于继承
简而言之,继承的功能非常强大,但是也存在诸多问题,因为它违背了封装原则。只有当子类和超类之间确实存在子类类型关系时,使用继承才是恰当的。即便如此,如果子类和超类处在不同的包中,并且超类并不是为了继承而设计的,那么继承将会导致脆弱性。为了避免,可以用复合和转发机制来代替继承,尤其是当存在适合的接口可以实现包装类的时候。包装类不仅比子类更加健壮,而且功能也更加强大。
17、要么为继承而设计,并提供文档说明,要么就禁止继承
18、接口优于抽象类
① 现有的类可以很容易被更新,以实现新的接口
② 接口的定义的理想选择
③ 接口允许我们构造非层次结构的类型框架
接口通常是定义允许多个实现的类型的最佳途径。这条规律有个例外,即当演变的容易性比灵活性和功能更为重要的时候。在这种情况下,应该使用抽象类来定义类型,但前提是必须理解并且可以接受这些局限性。如果你导出了一个重要的接口,就应该坚决考虑同时提供骨架实现类。最后,应该尽可能谨慎的设计所有的公有接口,并通过编写多个实现类对它们进行全面的测试。
19、接口只用于定义类型
接口应该只被用来定义类型,它们不应该被用来导出常量。
20、类层次优于标签类
标签类很少有适用的时候。当你想要编写一个包含显示标签域的类时,应该考虑一下,这个标签是否可以被取消,这个类是否可以用类层次来代替。当你遇到一个包含标签域的现有类时,就要考虑将它重构到一个层次结构中去。
21、用函数对象表示策略
要声明一个接口来表示该策略,并且为每个具体策略声明一个实现了该接口的类。当一个具体策略只被使用一次时,通常实现匿名类来声明和实例化这个具体策略类。当一个具体策略类是设计用来重复使用的时候,它的类通常就要被实现为私有的静态成员类,并通过公有的静态 final 域被导出,其类型为该策略接口。
22、优先考虑静态成员类
静态成员类、非静态成员类、匿名类、局部类
① 如果一个嵌套类需要在单个方法之外仍然是可见的,或者他太长了,不适合于放在内部,就应该使用成员类。
② 如果成员类的每个实例都需要一个指向其外围实例的引用,就要把成员类做成非静态的;否则就做成静态的。
③ 假设这个嵌套类属于一个方法的内部,如果你只需要在一个地方创建实例,并且已经有一个预置的类型可以说明这个类的特征,就要把它做成匿名类;否则,就做成局部类。
第四章 泛型
23、请不要在新代码中使用原生态类型
24、消除非受检警告
每一条警告都表示可能在运行时片抛出 ClassCastException 异常。要尽最大的努力消除这些警告。如果无法消除非受检警告,同时可以证明引起警告的代码是类型安全的,就可以在尽可能小的范围中,用 @SuppressWarnings("unchecked")注释禁止该警告。要用注释把禁止该警告的原因记录下来。
25、列表优先于数组
数组和泛型有着非常不同的类型规则。数组是协变且可以具体化的;泛型是不可变的且可以被擦除的。因此数组提供了运行时的类型安全,当时没有编译时的类型安全,反之,对于泛型也一样。一般来说,数组和泛型不能很好地混合使用。如果你发现自己将它们混合起来使用,并且得到了编译时错误或警告,应该用列表代替数组。
26、优先考虑泛型
27、优先考虑泛型方法
28、利用有限制通配符来提升API 的灵活性
29、优先考虑类型安全的异构容器
第六章 枚举和注解
30、用 enum 代替 int 常量
31、用实例域代替序数
32、用 EnumSet 代替位域
33、用 EnumMap 代替序数索引
34、用接口模拟可伸缩的枚举
35、注解优先于命名模式
36、坚持使用 Override 注解
37、用标记接口定义类型
第七章 方法
38、检查参数的有效性
39、必要时进行保护性拷贝
40、谨慎设计方法签名
① 谨慎地选择方法的名称
② 不要过于追求提供便利的方法
③ 避免过长的参数列表
41、慎用重载
“能够重载方法”并不意味着就“应该重载方法”。一般情况下,对于多个具有相同参数数目的方法来说,应该尽量避免重载方法。在某些情况下,特别是涉及构造器的时候,要遵循这条建议也许是不可能的。在这种情况下,至少应该避免这样的情形:同一组参数只需经过类型转换就可以被传递给不同的重载方法。
42、慎用可变参数
43、返回零长度的数组或者集合,而不是 null
44、未所有导出的 API 元素编写文档注释
第八章 通用程序设计
45、将局部变量的作用域最小化
46、for-each 循环优先于传统的 for 循环(除了 在过滤、转换、平行迭代下外)
47、了解和使用类库
48、如果需要精确的答案,请避免使用 float 和 double
49、基本类型优先于装箱基本类型
50、如果其他类型更适合,则尽量避免使用字符串
① 字符串不适合代替其他的值类型
② 字符串不适合代替枚举类型
③ 字符串不适合代替聚集类型
④ 字符串不适合代替能力表
51、当心字符串连接的性能
52、通过接口引用对象
53、接口优先于反射机制
反射的不足:
① 丧失了编译时类型检查的好处
② 执行反射访问所需要的代码非常笨拙和冗长
③ 性能损失
54、谨慎使用本地方法
55、谨慎地进行优化
56、遵守普遍接受的命名惯例
第九章 异常
57、只针对异常的情况才使用异常
58、对于可恢复的情况使用受检异常,对于编程错误使用运行时异常
59、避免不必要地使用受检的异常
60、优先使用标准的异常
61、抛出与抽象相对应的异常
62、每个方法抛出的异常都要有文档
63、在细节消息中包含能捕获失败的信息
64、努力使失败保持原子性
65、不要忽略异常
第十章 并发
66、同步访问共享的可变数据
67、避免过度同步
为了避免死锁和数据破坏,千万不要从同步区域内部调用外来方法。更为一般地讲,要尽量限制同步区域内部的工作量。
68、executor 和 task 优先于线程
69、并发工具优先于 wait 和 notify
70、线程安全性的文档化
71、使用延迟初始化
72、不要依赖于线程调度器
73、避免使用线程组
第十一章 序列化
74、谨慎地实现 Serializable 接口
使用此接口代价:
① 一旦一个雷被发布,就大大降低了“改变这个类的实现”的灵活性
② 增加了出现 Bug和安全漏洞的可能性
③ 随着类发行新的版本,相关的测试负担也增加了
75、考虑使用自定义的序列化形式
使用默认序列化形式缺点:
① 它使这个类的导出 API 永远地束缚在该类的内部表示法上
② 它会消耗过多的空间
③ 它会消耗过多的时间
④ 它会引起栈溢出
76、保护性地编写 readObject 方法
77、对于实例控制,枚举类型优先于 readResolve
78、考虑用序列化代理代替序列化实例
- 读《Effect Java中文版》
读<Effect Java中文版> 译者序 序 前言 第1章引言 1 第2章创建和销毁对象 4 第1条:考虑用静态工厂方法代替构造函数 4 第2条:使用私有构造函数强化singleto ...
- 《Effect Java》学习笔记1———创建和销毁对象
第二章 创建和销毁对象 1.考虑用静态工厂方法代替构造器 四大优势: i. 有名称 ii. 不必在每次调用它们的时候都创建一个新的对象: iii. 可以返回原返回类型的任何子类型的对象: JDBC ...
- Java正则表达式API详解
1. Pattern类 public class PatternExample { /** * public static String quote(String s) * 返回指定字符串的字面值模式 ...
- 深入理解 Java Object
Java中的Object对象为所有对象的直接或间接父对象,里面定义的几个方法容易被忽略却非常重要.以下来自Effective Java 对Object中几个关键方法的应用说明. public clas ...
- java异常处理Exception
我看别人的面经中有一道题目就问到了Exception,即java的异常处理的,我曾经也学了java的异常处理,可是我查了下,看了别人的博客关于写的exception异常处理.我发现,自己学的不坚固,仅 ...
- linux问题
make:进入目录'/opt/FriendlyARM/tiny4412/05android/android-4.1.2'target Dex: framework trouble writing ou ...
- Static 单例模式
Static 方法的问题 今天在看EhCache源码的时候,发现有一个这样的方法 这个是个典型的单例模式的工具类,但我所知道的单例模式的写法不是这样的,虽然<effect java>中 ...
- springboot 注册dao层 service 层
可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...
- sonar阻断级别错误(block)简单汇总
1.代码里面包含PASSWORD.PWD 'PWD' detected in this expression, review this potentially hardcoded credential ...
随机推荐
- Qt5官方demo解析集(36个)
http://blog.csdn.net/cloud_castle/article/category/2123873 http://blog.csdn.net/cloud_castle/article ...
- Android:安卓资源引用符号的含义
@代表引用资源 @*代表引用系统的非public资源,如: @*android:color/white @[package:]type/name引用自定义资源,如: android:text=&quo ...
- C#基础精华06(Linq To XML,读取xml文件,写入xml)
1.XML概述: 可扩展标记语言XML(eXtensible Markup Language)是一种简单灵活的文本格式的可扩展标记语言,侧重于存储数据. 2.XML特点 xml 标记语言 html x ...
- swap chain- IDirect3DSwapChain9
交换链,对应的接口是IDirect3DSwapChain9,是整个Directx 3D中最核心的接口.D3d程序至少包含一个swap chain,在调用CreateDevice时自动创建, 其中的D3 ...
- Android安全问题 抢先拦截短信
同上篇文章一样,这里只陈述结果,代码分析稍后给出 导读:本文叙述如何先于某些伪杀毒软件.病毒.常规软件获取到短信 众所周知,android系统在收到短信息的时候会发送广播,但是此广播是有序广播,也就是 ...
- 安装Hadoop系列 — 安装Hadoop
安装步骤如下: 1)下载hadoop:hadoop-1.0.3 http://archive.apache.org/dist/hadoop/core/hadoop-1.0.3/ 2)解压文 ...
- Java的类演进过程
1.从面向过程到面向对象 在大家最熟悉的C语言中,如果要定义一个复杂的数据类型就用结构体(Struct)来实现,而为结构体的每个操作都定义一个函数,这个函数与结构体本身的定义没有任何关系.程序的重心集 ...
- 制作计算器的代码(C#)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- WinCE启动失败的原因与解决办法分析
本文通过一个真实的嵌入式项目进行说明.文中的嵌入式系统用的是ARM处理器+WinCE平台,项目的目的是要把WinCE平台从旧版本移植到WinCE6.0平台上.但结果是这个WinCE系统在启动的时候经常 ...
- Android开发之在子线程中使用Toast
在子线程中使用Toast的时候,出现Force close. 错误提示:Can't create handler inside thread that has not called Looper.pr ...