【读书笔记】《Effective Java》(7)--通用程序设计

由至周末,再更新一章的笔记,做到后来发现,78条建议只读标题可以都懂一些东西,再都每一条里面的例子又是另外一些知识。

8. 通用程序设计

45. 将局部变量的作用于最小化(本条与第13条——使类和成员的可访问性最小化本质上是类似的)

  • 本条建议:
    1. 最有力的方法是在第一次使用局部变量的地方声明它:过早生命局部变量会扩展它的作用域,可能导致意外的发生;对于代码的阅读者来说,过早的声明一个没有用到的变量会让他们疑惑,分散注意力。
    2. 几乎每个局部变量的声明都应当包含一个初始化表达式:如果声明的时候不能进行有意义的初始化,那么就应该推迟这个声明。对此的一个例外是try-catch的语句,如果一个变量初始化可能抛出异常并且在try块之外还需要被使用,那么它可以在try块之前声明。
    3. 循环中提供了特殊的机会来使变量的作用域最小化:如果在循环终止之后不再需要循环变量的内容,for循环优先于while循环,因为for循环可以使局部变量的生命周期结束在{}
    4. 使方法小而集中:减少方法变量的交叉可以预防代码混乱出错。

46. for-each循环优先于传统的for循环

  • 不能使用for-each的情况:

    1. 过滤:遍历集合并删除元素的使用需要显式的迭代器,以调用remove方法
    2. 转换:便利集合并且需要部分取代它的元素时,需要迭代器或者数组索引
    3. 平行迭代:同时遍历多个集合,要求这多个集合同步前移的时候
  • 如果需要编写一个类型,来表示一组元素,那么即使不扩展Collection接口,也要实现Iterable接口,这样客户代码可以使用for-each遍历这个类的对象。


47. 了解和使用类库

  • 使用类库的好处:

    1. 无需关心实现细节:类库的方法大多经过严格的测试,值得信赖,就算有缺陷,也会在下一个发行版本中被修正。通过使用类库,可以充分利用编写标准类库的专家的知识,以及前人的使用经验。
    2. 不必浪费时间在与工作不太相关的问题上提供特别的解决方案。
    3. 可以使自己的代码融入主流,自己的代码更易读、易维护、更好重用。
  • 建议学习Java的人熟悉的类库:java.lang、java.util、java.io


48. 如果需要精确地答案,请避免使用float和double

  • float和double是为了在广泛的数值范围内提供较为精确的快速近似计算而设计的,但它们不能提供完全精确的结果,,它们无法精确地表示任何10的负次数幂。

  • 本条建议:使用BigDecimal、int、long类型进行货币计算。其中BigDecimal作为引用类型,提供了8种舍入模式,int和long则有较高的性能。

    如果数字没有超过9位十进制数字范围,可以使用int、没有超过18位十进制数字,可以使用long、超过18位十进制数字的话只能使用BigDecimal


49. 基本类型优先于装箱基本类型

  • 基本类型与基本装箱类型的区别:

    1. 基本类型只有值,装箱基本类型除了值还有与它们值不同的同一性(==的性质,引用地址不同)
    2. 基本类型只有功能完备的类,而装箱基本类型除了功能值之外还有null
    3. 基本类型比装箱基本类型更加节省时间和空间
  • 装箱基本类型的合理用途:

    1. 作为集合中的元素、键值,因为集合中不能存放基本类型
    2. 泛型中必须使用装箱基本类型作为类型参数
    3. 在反射的方法调用时,必须使用装箱基本类型
  • 装箱基本类型的问题(针对区别的三点):

    1. 当时用==比较两个装箱基本类型时,执行的是同一性比较,比较地址,这种比较多数情况下不是我们希望的
    2. 当涉及到装箱和拆箱基本类型时,遇到装箱基本类型是null的情况,拆箱会抛出NullPointerException异常
    3. 使用装箱基本类型会导致高开销和不必要的对象创建

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

  • 为什么不都是用String:
    1. String不适合替代其他类型的值,该是什么类型,就转换成什么类型
    2. String不适合代替枚举类型
    3. String不适合代替聚集类型。聚集类型,是指一个实体,有多个组件(属性)的情况,有人用String+分隔符表示一个聚集类型,但这种方法不好。如果用于分隔域的字符也出现在某一个域中会导致混乱, 而且访问单独的域需要解析字符串,这个过程比较繁琐耗时。
    4. String不适合代替能力表:有时会使用String作为某个条件判断某个功能是否可用(授权),但是String是存放在常量池中,可以被共享的,多个线程如果共享一个String,那么使用这个String判断授权就会产生问题。

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

  • String是不可变的,每一次连接字符串都会生成无用的中间字符串,影响性能。为连接n个字符串而重复使用字符串连接操作,需要n的平方级的时间。

  • 本条建议:使用StringBuilder代替String


52. 通过接口引用对象(类似与第0条提到的使用接口而不是类作为参数的类型)

  • 使用接口的好处:隐藏了内部实现,方便后续版本更改内部实现而无需更换API

  • Java中的典型使用:ThreadLocal类:这个类内部有一个包级私有的Map域,1.3版本中使用HashMap,1.4版本中更改为专用的IdentityHashMap,然而这对于客户代码没有带来影响。

  • 不适合使用接口引用对象的情况:

    1. 如果没有合适的接口存在,完全可以使用类而不是接口来引用对象:比如值类和具体的类
    2. 对象属于一个框架,而这个框架的基本类型就是类
    3. 类实现了接口,但是它提供了接口不存在的额外方法:比如LinkedHashMap、Vector。如果程序依赖于这些额外的方法,就应当使用类,而不是接口引用。

53. 接口优先于反射机制

  • 反射的缺点:

    1. 失去了编译时类型检查额好处
    2. 执行反射访问所需要的代码非常笨拙而冗长
    3. 性能损失
  • 反射和接口相配合:对于有些程序,它们必须要用到在编译时无法获取的类,这是可以通过编译时存在适当的接口或者引用这个类。即通过反射创建实例,然后通过它们的接口或者超类,以正常的方式访问这些实例。


54. 谨慎地使用本地方法

  • 本地方法:本地程序设计语言来编写的特殊方法,本地方法在本地语言中可以执行任何的计算任务,并返回到Java程序设计语言。

  • 本地方法的用途:

    1. “访问特定于平台的机制”的能力,比如注册表、文件锁
    2. 访问遗留代码库的能力。
    3. 通过本地语言,编写程序中注重性能的部分,提高系统的性能
  • 不推荐本地方法的原因:

    1. 随着Java平台的不断发展,它提供了越来越多以前只有宿主平台才拥有的特性。
    2. JVM正在变得越来越快,使用本地方法提高性能的做法也就不值得推荐了
    3. 使用本地语言是不安全的,Java无法防止本地方法中对内存的破坏
    4. 本地方法与平台相关,使用本地方法的应用程序的可移植性更差
    5. 本地方法的调用更难调试

55. 谨慎地选择优化

  • 本条建议:
    1. 好的结构优先于性能:好的结构影响整个程序的体系,一旦形成再难更改,而性能调优则可以在后期慢慢进行
    2. 好的设计模式(API的设计)优先于性能:两者相比,好的设计模式更重要,或者说好的设计会带来好的性能,二者不矛盾
    3. 在性能剖析工具的帮助下,选择优化的重点

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

  • 字面命名惯例:
    1.包的命名:有层次的,以句点分开;每部分包含小写字母和数字(很少使用数字);任何将本组织之外使用的包,以名称以本组织的Internet域名开头,并且顶级域名放在前面;包名的剩余部分应该包含一个或多个描述该包的组成部分

    1. 类和接口的命名:一个或多个单词,每个单词首字母大写,避免使用缩写;
    2. 方法和域、局部变量的命名:类似于类和接口的命名,一个明显的区别是方法和域的第一个单词首字母小写;一个例外是常量域应当所有字母大写,多个单词以下划线分开
    3. 类型参数的命名:T代表任意类型;E代表集合的元素类型;K和V代表键值对的类型;X代表异常;任何类型的序列可以使T、U、V或者T1、T2、T3
  • 语法命名惯例:

    1. 类的命名:通常是一个名词或者名词短语
    2. 接口的命名:与类相似,可以以-able或者-ible结尾的形容词命名
    3. 执行某个动作的方法命名:以动词或者动词短语明明
    4. 返回boolean的方法命名:往往以“is”开头,很少用“has”,后跟名词或者名词短语
    5. 返回非boolea的方法命名:通常用名词、名词短语,或者“get”开头的动词短语
    6. 特别的方法命名:

    • 转换对象类型的方法、返回不同类型的独立对象的方法:形式如toType
    • 返回视图的方法:形式如asType
    • 返回要给与被调用对象同值的基本类型的方法:形式如typeValue
    • 静态工厂的常用名称:valueOf、of、 getInstance、newIntance、getType、NewType

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值