通用程序设计
1.将局部变量作用域最小化
如果过早声明变量,程序员在理解代码的时候可能会记不起来这个变量的初始值了。并且过早声明变量会使作用域变广,可能会在不该被使用的地方被引用。
要把局部变量最小化,最有力的方法就是在第一次使用它的时候声明它。 基本上全部局部变量都有初始值,我们需要有初始化所需要的全部信息以后才初始化它。(try catch语句除外) 在这一方面,for循环做的非常好,初始化的循环变量i在合适的位置初始化了,在for结束后i作用域消失。而while循环把变量声明在外,在while结束后,i仍然有效,可能会出复制粘贴bug。 如果把两个操作写到一个方法中,一个操作的局部变量的作用域在另外一个操作里面,可以把原来的一个方法拆成两个方法,每个方法执行一个操作。2. 如果想要精确的答案,避免使用double和float
我们想知道1.03元花掉0.42元后还有多少钱
#!javaSystem.out.println(1.03-0.42);>>0.6100000000000001
很明显答案是有问题的,有时候我们需要讲计算出的数据判断是否相等,这种情况下对答案舍入也没办法接受的。
#!javaBigDecimal a = new BigDecimal("1.03");BigDecimal b = new BigDecimal("0.42");System.out.println(a.subtract(b));>>0.61
这样写虽然很罗嗦而且性能低下,但是还是有一些好处的
- 获得的数据精确
- BigDecimal可以完全控制舍入(有8种模式)
3. 优先使用基本类型
我相信没有多少程序员会在代码中到处使用装箱类型,所以只谈论一下基本类型和装箱类型之间需要注意的区别。
- 基本类型只有值,装箱类型有与值不同的东西,例如
Integer
从-256到256都是由数组缓存的,在256后都要new一个出来 - 装箱类型有一个基本类型没有的值
null
- 基本类型比装箱类型更节省空间和时间
3.1 不要在装箱类型上使用==
基本上有在装箱类型上有用到==的情况基本上都是错误的,我们看一下下面的例子
#!javaSystem.out.println(new Integer(5)==new Integer(5));>>false
由于没有自动拆箱,并没有提取他们的基本类型的值,而是比较这两个引用是否指向了同一个对象。
3.2 注意装箱类型在类中的初始值
在类中声明基本类型时,初始值默认为0,但是在装箱类型中,初始值默认为null。
下面的代码会抛出空指针错误。#!javapublic class Unbelieable { static Integer i; public static void main(String[] args) { System.out.println(i==0); }}
3.3用到装箱类型的情况
- 作为集合中的key和value
- 在泛型中使用
- 在反射的方法中调用
4. 通过接口引用对象
在声明对象或者方法引用对象的时候,如果有合适的接口选择,我们优先使用接口来声明。例如我们用List接口来代替ArrayList声明列表(这段代码在安卓很常见)
#!javaListbeans = new ArrayList<>();
使用这种方法声明,当你想换实现方式的时候,比如想用LinkedList代替ArrayList时,只需要改变一个地方即可。从上面可以看出来使用接口引用对象灵活了许多。