规范化代码
局部变量作用域最小化
不要在方法开始时,就声明所有变量<在方法中使用时需要到方法开始位置确认局部变量类型>。在使用变量时再声明也来得及。
使用时声明局部变量
使用前声明变量,容易分散注意力。
for循环优先于while循环
简洁性更好,可读性更高。
List<String> list = new ArrayList<>();
for (String s: list) {
}
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
}
使方法小而集中
每个方法专注完成一件事,移除无用参数。
foreach循环优于传统for循环
foreach循环完全隐藏迭代器和索引变量,避免出错。
不适合使用foreach循环的情况:
- 解构过滤。例如遍历集合,删除指定元素,需要使用显示的迭代器。
- 转换。例如遍历集合,取代部分或者全部元素值,需要使用集合迭代器或集合索引,方便设值。
- 平行迭代。例如并行遍历过个集合,需要控制迭代器或索引变量,以便所有迭代器或索引都可以同步前进。
了解和使用标准类库
- 使用标准类库,可以使用编写标准类库的专家的知识。
举例java7开始,选择使用 ThreadLocalRandom,不再使用Random。 - 不必为工作不想关的问题提供特别的解决方案。
- 标准类库的性能会随着时间推移不断提高。
- 标准类库会随着时间增加新功能。
推荐熟悉 java.lang、java.util、java.io及其子包中的内容。
追求精准的答案,避免使用float和double
使用BigDecimal、int、long进行货币计算。
推荐以分为单位进行货币计算。
基本类型优于装箱基本类型
基本类型、装箱基本类型区别
- 基本类型中只有值,装箱基本类型具有和值不同的同一性。举例:两个装箱基本类型可以有相同值和不同的同一性。
- 基本类型中只有函数值,装箱基本类型都有一个非函数值<基本类型中的所有函数值+null>。
- 基础类型比装箱基本类型更节省时间和空间。
注意
- 对装箱基本类型使用 == 操作符几乎总是错误的。
- 当一项操作中混合使用基本类型和装箱基本类型时,装箱基本类型会自动拆箱。举例:声明 Integer i后,使用if (i = 10)判断,此时会抛出NullPointerException异常。
- 自动装箱减少了使用装箱基本类型繁琐性,但是没有减少风险。
- 程序装箱了基本类型时,会导致较高的资源消耗和不必要的对象创建<相对于基本类型来说>。
如果有更适合的类型,尽量避免使用字符串
- 可以使用更加合适的数据类型,就应该尽量避免使用字符串。
- 不要使用字符串代替基本类型、枚举类、聚合类型。
了解字符串连接性能
轻易不要选择字符串连接,除非性能无关紧要。
打印日志时,推荐使用占用符,不要使用字符串连接。
优先通过接口引用对象
如果有合适的接口类型存在,那么对于参数、返回值、变量和属性来说,就应该使用接口类型声明。使用接口作为类型,程序更加灵活。
接口优先于反射机制
反射有很多优点:
- 给定一个Class对象,可以获得Constructor、Method和Field实例,分别代表类的构造器、方法、属性。
- 使用反射可以执行类的构造器、方法,访问属性。
当然也有缺点:
- 损失了编译时类型检查的优势。
- 执行反射访问所需要的代码比较笨拙和冗长。
- 性能损失。 不过这个性能损失一般开发时,不做考虑,除非达到一定级别,压测验证后,再下定结论。
谨慎使用本地方法
一个native method就是一个Java调用非Java代码的接口。一个native method就是这样一个Java方法:该方法的实现由非Java语言实现的,比如C。
谨慎优化代码
- 努力编写好的程序而不是快的程序。不要因为性能牺牲合理的结构。
- 避免限制性能的设计决策。
- 考虑api设计到的性能后果。
- 在优化前后,对性能进行测量。
遵守普遍遵守的命名惯例
推荐阅读:the java language specification