Effective Java读书笔记四:通用程序设计(45-56)

第45条:将局部变量的作用域最小化

  1. 在第一次使用变量时的地方声明;
  2. 几乎每个局部变量的声明都应该包含一个初始表达式;
  3. 如果在终止循环之后不需要循环变量的内容,for循环优于while循环。(for循环比while循环还有个优势:更简洁,增强可读性)
for(int i =0,n = expensiveComputation(); i < n; i ++){
  doSomething(i);
}

关于这种做法要关注的一点是,它具有两个循环变量:i和n,两者具有相同的作用域。第二个变量n被采用来保存第一个变量的极限值,从而避免在每次迭代中执行冗余计算的开销。通常,如果循环测试中涉及方法调用,它可以保证每次迭代都会返回同样的结果,就应该使用这种做法。

第46条:for-each循环优先于传统的for循环

1.对于多个集合进行嵌套迭代时,for-each循环优势更明显.
2.for-each循环不仅可以遍历集合、数组和枚举,还可以遍历任何实现Iterable接口的对象。
3.无法使用for-each循环的情况:
  过滤–如果需要在集合上遍历且移去选定的元素,就要使用显式的迭代,并调用它的remove方法。
  转换–如果需要在list或数组上遍历且要替换部分或所有的元素值,则需要list的迭代器或数组的索引去设置这些值。
  平行迭代–如果需要并行的遍历多个集合,则需要显式的控制迭代器或索引变量,以便所有的迭代器或索引能协同推进。

第47条:了解和使用标准类库

1、通过使用标准类库,可以充分利用这些编写标准类库专家的知识,以及在你之前的其他人的使用经验。
2、不必将你的时间浪费在与你工作基本无关的问题上。与大多数程序员一样,你应该将你的时间放在你的应用研发上,而不是底层细节上。
3、无需你的努力,标准类库的性能会随着时间的推迟而改善。因为类库被许多人使用,也因为类库以工作标准基准被使用,所以类库的供应商有着强烈的动机让类库运行得更快。
4、可以使你的代码融于主流中,这种类码更易读,更易维护,更易被大多数开发者重用。

第48条:如果需要精确的答案,请避免使用float和double

1、float和double类型尤其不适合用于货币计算
2、可以使用bigDecimal、int或者long进行货币计算(BigDecimal不方便而且慢,如果数值范围没有超过9位十进制数字,就可以使用int;如果不超过18位数字,就可以使用long;如果可能超过18位,就必须使用BigDecimal)

第49条:基本类型优先于装箱基本类型

基本类型和装箱基本类型的区别:
1.基本类型只有值,而装箱基本类型则具有与它们的值不同的同一性。
2.基本类型只有功能完备的至,而每个装箱基本类型除了它对应基本类型的所有功能值之外,还有个非功能值:null。
3.基本类型通常比装箱基本类型更节省时间和空间。

装箱基本类型的合理用处:
1.作为集合中的元素、键和值。你不能将基本类型放在集合中,因此必须使用装箱基本类型。
2.在参数化类型中,必须使用装箱基本类型作为类型参数,因为Java不允许使用基本类型。
3.在进行反射的方法调用时,必须使用装箱基本类型。

当可以选择的时候,基本类型要优于装箱基本类型。基本类型更加简单,也更加快速。如果必须使用装箱基本类型,要特别小心!自动装箱减少了使用装箱基本类型的繁琐性,但是并没有减少它的风险。当程序使用==操作符比较两个装箱基本类型时,它做了个同一性比较,这几乎肯定不是你所希望的。当程序进行涉及装箱和拆箱基本类型的混合计算时,它会进行拆箱,当程序进行拆箱时,会抛出NullPointerException异常。最后,当程序装箱了基本类型值时,会导致高开销和不必要的对象创建。

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

  1. 字符串不适合代替其他的值类型
    当一段数据从文件、网络、或者键盘设备,进入到程序之后,它通常以字符串的形式存在。有一种自然的倾向是让它继续保留这种形式,但是,只有当这段数据本质上确实是文本信息时,这种想法才是合理的。
  2. 字符串不适合替代枚举类型
    枚举类型比字符串更加适合用来表示枚举类型的常量
  3. 字符串不适合代替聚集类型
    如果一个实体有多个组件,用一个字符串来表示这个实体通常是不恰当的
String compoundKey = className + "#" + i.next();

这种方法有许多缺点。如果用来分割域的字符串也出现在某个域中,结果就会出现混乱。为了访问单独的域,必须解析该字符串,这个过程非常慢,也很繁琐,还容易出错。你无法提供equals、toString或者compareTo方法,只好被迫几首String提供的行为。更好的做法是,简单的编写一个类来描述这个数据集,通常是一个私有的静态成员类。
4. 字符串不适合代替能力表 有时候,字符串被用于某种功能进行授权访问。

如果可以使用更加合适的数据类型,或者可以编写更加合适的数据类型,就应该避免用字符串表示对象。若使用不当,字符串会比较其他类型更急笨拙、更加不灵活、速度更慢,也更容易出错。经常被错误的用字符来代替的类型包括基本类型、枚举类型和聚集类型。

第51条:当心字符串连接的性能

  1. 为连接n个字符串而重复使用字符串连接符(+),需要n的平方级时间。这是由于字符串不可变,当两个字符串被连接在一起时,他们的内容都要被拷贝。
  2. 当我们的程序需要性能的时候,不要使用字符串连接操作符(+)来合并多个字符串 。最好使用StringBuilder的append方法。
  3. StringBuilder类是非线程,StringBuffer是线程安全的

第52条:通过接口引用对象

1、优先使用接口而不是类来引用对象。
如果有合适的接口类型存在,那么对参数、返回值、变量和域来说,就应该使用接口类型进行声明。
只有当利用构造器创建某个对象的时候才真正需要引用这个对象的类

List<Subscriber> subscribers = new ArrayList<Subscriber>();

2、 如果没有合适的接口存在,完全可以用类而不是接口来引用对象,有三种情况:

  • 具体类没有相关联的接口,例如:Random类;
  • 对象属于基于类的框架,例如TimerTask抽象类;
  • 类实现了接口,但它提供了接口中不存在的而外方法,例如:LinkedHashMap,如果程序依赖这些额外的方法,这种类就应该只被用来引用它的实例。

第53条:接口优先于反射机制

1、反射机制(reflection)允许一个类使用另一个类,即使当前者被编译的时候还根本不存在。然而这样做要付出代价:

  • 丧失了编译时类型检查的好处;
  • 执行反射访问所需要的代码非常笨拙和冗长;
  • 性能损失。反射方法的调用比普通方法调用慢了许多。
  • 反射功能只是在设计时被用到,普通应用程序运行时不应该以反射方式访问对象。

2、反射机制的作用:
对于有些程序,它们必须用到在编译时无法获取的类,但在编译时存在适当的接口或者超类,通过它们可以引用这个类。如果是这种情况,就可以以反射的方式创建实例,然后通过它们的接口或者超类,以正常的方式访问这些实例。如果适当的构造器不需要任何参数,那就不需要使用java.lang.reflect包,采用Class.newInstace方法就可以了。

第54条:谨慎地使用本地方法

使用本地方法的重要缺点:本地语言不是安全的;本地语言是与平台相关的。

第55条:谨慎地进行优化

不用费力去编写快速的程序–应该努力编写更好的程序,速度自然会随着而来。

第56条:遵守普通接受的命名惯例

可以参考各大公司的开发手册中的命名规范
阿里巴巴Java开发手册(正式版)

《Effective Java中文版 第2版》PDF版下载:
http://download.csdn.net/detail/xunzaosiyecao/9745699

作者:jiankunking 出处:http://blog.csdn.net/jiankunking

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值