《effective java》条目总结

清晰性和简洁性最重要

模块尽可能小

重用代码

模块间依赖性尽可能小

错误尽早被检测出来

二.创建和销毁对象

1.考虑用静态工厂方法代替构造器(服务提供者框架)

2.遇到多个构造参数时考虑用构造器(建造者模式)

3.用私有构造器或者枚举类型强化单例属性

4.通过私有构造器强化不可实例化能力

5.避免创建不必要的对象(优先使用基本类型,当心无意识的自动装箱)

6.消除过期对象的引用(类是自己管理内存时,要小心。2.缓存3.监听器和回调)

7.避免使用终结方法(显示关闭)

三.对于所有对象都通用的方法

8.覆盖equals时请遵守通用约定(等价关系:自反性,对称性,传递性,一致性)

(高质量equals诀窍:1.使用==检查参数是否为这个对象的引用

2.用instanceof检查参数是否为正确的类型

3.把参数转换为正确的类型

4.对于该类的每个“关键”域检查参数中的域是否和对象对应的域相匹配

5.问自己3个问题,是否对称,传递,一致

不要将object对象替换为其他类型)

9.覆盖equals时总要覆盖hashcode

10.始终要覆盖toString()

11.谨慎地覆盖clone(clone()就是另一个构造器,必须确保它不会伤害到原始对象并正确地创建被克隆对象中的约束)

12.考虑实现comparable接口

四.类和接口

13.使类和成员的可访问性最小化(实例域决不能是公有的)

14.在公有类中使用访问方法而非公有域

15.使可变性最小化

(不可变类规则:1.不提供任何会修改对象状态的方法

2.保证类不会被扩展

3.使所有的域都是final

4.使所有的域都成为私有

5.确保对任何可变组件的互斥访问)

16.复合优先于继承

17.要么为继承而设计,并提供文档说明要么禁止继承(构造器决不能调用可被覆盖的方法)

18.接口优于抽象类

19.接口只用于定义类型

20.类层次优于标签类

21.用函数对象表示策略

22.优先考虑静态成员类(如果声明成员类不要求访问外围实例,就要使它成为静态成员类)

五.泛型

23.请不要在新代码中使用原生态类型

24.消除非受检警告

25.列表优先于数组

26.优先考虑泛型(只要时间允许,就把现有的类型都泛型化)

27.优先考虑泛型方法(静态工具方法尤其适合泛型化)

28.利用有限制通配符来提升api的灵活性(PECS:生产者继承,消费者-super

不要用通配符类型作为返回类型,所有的comparable..comparator都是消费者)

29.优先考虑类型安全的异构容器

六.枚举和注解

30.用enum代替int常量

31.用实例域代替序数

32.用EnumSet代替位域

33.用EnumMap代替序数索引

34.用接口模拟可伸缩的枚举

35.注解优先于命名模式

36.坚持使用Override注解

37.用标记接口定义类型

七.方法

38.检查参数的有效性

39.必要时进行保护性拷贝(对于参数类型可以被不可信任方子类化的参数,请不要用clone方法进行保护性拷贝;只要有可能尽量用不可变对象作为组件)

40.谨慎设计方法签名(谨慎地选择方法的名称,不要过于追求提供便利的方法,避免过长的参数列表;

缩短参数长度方法:1.把方法分解成多个方法

2.创建辅助类3.建造者模式;boolean参数,要优先使用两个元素的枚举类型)

41.慎用重载(重载方法选择是静态的,覆盖方法选择是动态的,保守策略:永远不要导出两个具有相同参数数目的重载方法,对可变参数不要重载)

42.慎用可变参数

43.返回零长度的数组或集合,而不是null

44.为所有导出的API元素编写文档注释(熟悉文档注释规范;应说明方法做了什么,前提,后置条件,副作用,线程安全性,可序列性;方法和构造器概要描述:动词短语,类和接口:名词短语;)

八.通用程序设计

45.将局部变量的作用域最小化(第一次使用它的地方声明,包含初始化表达式;使方法小而集中)

46.foreach优于传统的for循环(可遍历任何实现iterable接口的对象;无法使用的情况,过滤,转换,平行迭代)

47.了解和使用类库(lang.util.io.concurrent.collections) 要多了解

不要重复发明轮子

48.如果需要精确的答案,请避免使用float,double(正确的办法是使用bigdecimal,int,long进行货币计算;如果数值可能超过18位数字必须使用bigdecimal)

49.基本类型优于装箱基本类型(集合中的键值,参数化类型时只能用包装类型)

50.如果其他类型更合适,则尽量避免使用字符串

51.当心字符串连接的性能(stringbuilder)

52.通过接口引用对象(或类层次结构的基类,因为更灵活)

53.接口优于反射机制(仅仅使用反射机制实例化对象,访问对象则使用编译时已知的某个接口或者超类)

54.谨慎地使用本地方法(不安全)

55.谨慎地进行优化(努力编写好的程序,在设计时对api,线路层协议,数据结构考虑性能问题。  好性能自然会来)

56.遵守普遍接受的命名惯例

九.异常

57.只针对异常情况才使用异常

58.对可恢复的情况使用受检异常,对编程错误使用运行时异常

59.避免不必要地使用受检的异常

60.优先使用标准的异常

61.抛出与抽象相对应的异常(异常转译:更高层的实现应该捕获低层的异常,同时可以抛出按高层抽象进行解释的异常;异常链)

62.每个方法抛出的异常都要有文档

63.在细节消息中包含能捕获失败的信息(细节消息应该包含有贡献的参数和域)

64.努力使失败保持原子性(在执行操作之前检查参数的有效性;使任何可能失败的计算部分都在对象状态修改之前发生;编写一段恢复代码;在对象的一份临时拷贝上执行操作,再写回)

65.不要忽略异常

十.并发

66.同步访问共享的可变数据(将可变数据限制在单个线程中;安全发布;共享可变数据需要同步)

67.避免过度同步(不要从同步区域调用外来方法;尽量限制同步区域内部的工作量)

68.executor和task优先于线程

69.并发工具优先于wait,notify(对于间歇式定时,始终应该优先使用namoTime)

70.线程安全性的文档化

71.慎用延迟初始化

72.不要依赖于线程调度器(线程不应该一直处于忙-等)

73.避免使用线程组

十一.序列化

74.谨慎地实现Serializable接口(为继承设计的类和用户的接口尽可能地少继承Serializable接口;内部类不应该实现。。。接口,静态成员类可以)

75.考虑使用自定义的序列化形式(一个对象的物理表示法等同于它的逻辑内容,可能就适合使用默认序列化形式;编写一个显式的序列化uid)

76.保护性地编写readObject方法

77.对于实例控制,枚举类型优先于readResolve

78.考虑用序列化代理代替序列化实例

你可能感兴趣的:(《effective java》条目总结)