51.当心字符串连接的性能
简单来说当需求需要使用大批量的字符串拼接时不要用String的+号拼接,建议使用StringBuilder.代码示例如下
public static void main(String[] args) {
long begin = System.currentTimeMillis();
String sum = "";
for(int i =0; i<=10000;i++){
sum = sum + i;
}
long end = System.currentTimeMillis();
System.out.println("String总耗时:"+(end - begin));//446ms
//快速
long begin1 = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for(int i =0; i<=10000;i++){
stringBuilder.append(i);
}
long end1 = System.currentTimeMillis();
System.out.println("StringBuilder总耗时:"+(end1 - begin1));//0ms
//安全
long begin2 = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for(int i =0; i<=10000;i++){
stringBuffer.append(i);
}
long end2 = System.currentTimeMillis();
System.out.println("StringBuffer总耗时:"+(end2 - begin2));//2ms
}
52.面向接口编程
当我们在实例化对象的时候要尽量做到面向接口编程,这样当我们需要更换实现对象的时候,会更加便捷
- 错误做法
ArrayList arrayList = new ArrayList();
- 正确做法
List list = new ArrayList();
53.接口优先于反射机制
- 使用反射的缺点
- 丧失了编译时期类型检查的好处.获取字节码对象的方式有如下三种,只有第二种方式才是我们对一个类的访问权限不足的时候可以使用的,然而也是这种方法的风险是最大的(如代码示例1所示)
- 执行反射访问所需要的代码非常的笨拙和冗长
- 性能上的损失.反射方法获取的方式是从类加载器当中去获取字节码对象到堆空间当中去运行,而普通方法本身对象就存在于堆空间中,两者性能相比自然有着较大的区别
代码示例1
public class Test {
public static void main(String[] args) {
//方式1:
Class<? extends Test> aClass = new Test().getClass();
//方式2:
try {
Class clazz = Class.forName("com.zengtengpeng.test.Test");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//方式3:
Class<Test> testClass = Test.class;
}
}
54.谨慎使用本地方法(native修饰的方法)
- 54.1 本地方法不安全
- 54.2 Java本身是跨平台的,但是native修饰的方法时不跨平台的
- 54.3 native方法大多是不开源的,查询实现逻辑比较有难度
55.谨慎地进行优化
- 55.1 很多计算机上的过失都被归咎于效率(没有必要达到的效率),而不是任何其他的原因,甚至包括盲目的做傻事
引用自William A.Wulf
- 55.2 不要去计较效率上的一些小小的得失,在97%的情况下,不成熟的优化才是一切问题的根源.
引用自Donald E.Knuth
- 55.3 在优化方面,我们应该遵守两条规则
- 规则1:不要进行优化
- 规则2:(仅针对专家),还是不要进行优化,也就是说,在你还没有绝对清晰的来优化方案之前,请不要进行优化
引用自M.A.Jackson
总结:大佬们叫我们不要优化的前提是我们的代码已经遵守了我们定制的所有规则,可以参考阿里巴巴开发规范手册.在这个前提下,其实已经没有什么可以过多优化的空间了,那么久不要再进行优化了
不要费力去编写快速的程序,应该努力去编写好的程序
56.遵守普遍接受的命名规则
推荐官方命名文档
引用该文档的一句话来进行总结:"如果长期养成的习惯与此不同,那么请不要盲目的去遵从这些命名惯例"
57.只针对代码中无法确定的情况再使用异常
- 57.1 在开发当中不要随意使用try-catch代码块,只有当这部分代码涉及到的资源可能存在不确定性,那么我们才使用可能出现的异常的情况去捕获它并且记录它
- 57.2 如果一定需要使用到try-catch,那么要保证它所包含的代码尽可能的少
58.自定义异常应该是业务逻辑异常
- 58.1 编译时期异常应该在运行前解决
- 58.2 自定义的异常仅用于弥补业务逻辑可能存在的漏洞
59.避免不必要的使用受检查的异常
在日常开发规范当中,我们要尽量使用对应错误码,使用固定的错误格式来替代异常返回,这样更有益于程序的规范
60.优先使用标准的异常
总而言之,如果在JDK当中已经存在这种类型的异常了,那么久不要再自己重新去定义一个新的异常来表示