8、通用编程
57、将局部变量的作用域最小化
- 最有力的方法就是在第一次使用它的地方进行声明;
- 几乎每一个局部变量的声明都应该包含一个初始化表达式;
- for循环优先于while循环;
- 将局部变量的作用域最小化的方法是“使方法小而集中”;
58、for-each循环优先于传统的for循环
- 有三种常见的情况无法使用for-each循环:
- 解构过滤:删除元素,需要用显式的迭代器 ;
- 转换 :遍历列表或者数组,并取代它的部分或全部元素值;
- 平行迭代:并行遍历多个集合,就要显式地控制迭代器或者索隐变量;
59、了解和使用类库
- ThreadLocalRandom 代替 Random;
- 在每一个重要版本发布的时候,都有许多新的特续被加入到类库中;
- 主要java.lang、java.util、java.io;
- google开源类库【Guava】
60、如果需要精确的答案,请避免使用float和double
- float和double类型(主要是为了科学计算和工程计算而设计的,执行二进制浮点运算)尤其不适合用于货币计算
- 使用BigDeciml、int或者long进行货币计算
61、基本类型优先于装箱基本类型
- 对装箱基本类型运用 == 操作符总是错误的;
- 当在一项操作中混合使用基本类型和装箱基本类型时,装箱基本类型就会自动拆箱;
62、如果其他类型更适合、则尽量避免使用字符
63、了解字符串连接的性能
- 字符串连接操作符(+);
- 为连接n个字符串而重复使用字符串连接符,需要n的平方级的时间;
- 不要使用字符串连接操作符来合并多个字符串,除非性能无关紧要,应该使用StringBuilder的append方法;
64、通过接口引用对象
- 如果有合适的接口类型存在,那么对于参数、返回值、变量和域来说,就都应该使用接口类型进行声明;
- 如果养成了用接口作为类型的习惯,程序就会更加灵活;
- 如果没有合适的接口存在,完全可以用类而不是接口来引用对象;、
65、接口优先于反射机制
- 用反射的方式创建实例,然后通过它们的接口或超类,以正常的方式访问这些实例;
//throws ClassNotFoundException
Class<? extends Set<String>> cl = (Class<? extends Set<String>>)Class.forName(args[0]);;
//throws NoSuchMethodException
final Constructor<? extends Set<String>> cons = cl.getDeclaredConstructor();
//throws IllegalAccessException, InvocationTargetException, InstantiationException
final Set<String> set = cons.newInstance();
//set操作
66、谨慎使用本地方法
67、谨慎地进行优化
68、遵守普遍接受的命名惯例
- 包模块 小写
- 类和接口 首字母大写
- 方法和域 首字母小写
- 常量域 全大写,下划线隔开单词
9、异常
69、只针对异常的情况才使用异常
- 异常应该只用于异常的情况下;它们永远不应该用于正常的控制流;
- 设计良好的API不应该强迫它的客户端为了正常的控制流而使用异常;
70、对可恢复的情况使用受检异常,对于编程错误使用运行时异常
- Java提供了三种可抛出异常:受检异常、运行时异常、错误;
- 如果期望调用者能够适当地恢复,对于这种情况就应该使用受检异常;
- 用运行时异常来表示编程错误;例如ArrayIndexOutOfBoundsException
- 你实现的所有未受检的抛出结构都应该是RuntimeException的子类;
71、避免不必要地使用受检异常
72、优先使用标准异常
- 异常类越少,意味着内存占用就越小,装载这些类的时间开销也越小;
73、抛出与抽象对应的异常
- **更高层的实现应该可以捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常;**这种做法被称为异常转译
- 尽管异常转译与不加选择地从低层传递异常的作法相比有所改进,但是也不能滥用它;
74、每个方法抛出的所有异常都要建立文档
- 始终要单独地声明受检异常;
- 通过Javadoc的**@throws 标签** 准确地记录下抛出的每个异常的条件;
- 永远不要声明一个公有方法直接“throws Exception”或“threws Throwable”
75、在细节消息中包含失败-捕获信息
- 为了捕获失败,异常的细节信息应该包含“对该异常有贡献”的所有参数和域的值
- 千万不要在细节消息中包含密码、密钥以及类似信息;
76、努力使失败保持原子性
- 一般而言,**失败的方法调用应该使对象保持在被调用之前的状态;**即:失败原子性
77、不要忽略异常
- 空的catch块使异常达不到应有的目的;
- 如果选择忽略异常,catch块中应该包含一条注释,说明为什么这么做。并且变量名应该命名未ignored
参考资料:《Effective Java》第三版