本文参考整理自https://mp.weixin.qq.com/s/-u6ytFRp-ZAqdLBsMmuDMw
对于在本文中有所疑问的点可以去该文章查看详情
常量&变量
直接赋值常量值, 禁止声明新对象,如
Long i = new Long(1L);
当成员变量值无需改变时, 尽量定义为静态常量
尽量使用基本数据类型, 避免自动装箱和拆箱
如果变量会被覆盖就没必要赋初值
尽量使用函数内的基本类型临时变量
函数内, 基本类型的参数和临时变量都保存在栈中, 访问速度较快. 对象类型的参数和临时变量和引用都保存在栈中, 而内容都保存在堆中, 访问速度较慢
在类中, 任何类型的成员变量都保存在堆中
尽量不要在循环体外定义变量, 避免延长大对象生命周期导致延缓回收问题
不可变的静态常量和成员变量, 尽量使用非线程安全类
对象&类
禁止使用JSON转化对象, 应该手动包装来转化对象
先转化为JSON字符串再转为对应对象可以实现转化对象, 但是性能上存在问题
尽量不使用通过反射赋值对象, 会造成性能下降, 比如DTO取值赋值到VO
匿名内部类采用Lambda表达式, 因为Lambda表达式在大多数虚拟机中采用invokeDynamic指令实现, 效率会比匿名内部类更高
尽量避免定义不必要的子类,多一个类就需要多一份类加载
尽量指定类和方法的final修饰符
Java编译器会寻找机会内联所有的final, 具体参见Java运行期优化, 能够使性能平均提高50%
方法
把和类成员变量无关的方法声明为静态方法
尽量使用基本数据类型作为参数类型和返回值类型, 避免不必要的装箱拆箱和空指针判断
协议编程, 协议方法参数值与返回值非空
避免多余的判空处理
避免不必要的函数封装, 方法调用引起的额入栈和出栈会导致更多的CPU和内存消耗, 不过为了代码的简洁和清晰, 增加一定的方法是值得的
减少方法的重复调用
for (int i = 0, userLength = userList.size(); i < userLength; i++) {
...
}
尽量避免不必要的方法调用, 其实就是避免出现 调用了一个方法并将结果赋值, 赋的值还未起到作用, 就被覆盖了 的情况发生
尽量使用移位来代替正整数乘除
提取公共表达式
尽量少在条件表达式中用 ! 取反
当高于5个分支时, switch语句效率更高, 而非if else
字符串
尽量不要使用正则表达式匹配
尽量使用字符替换字符串, 因为字符长度固定为1, 查找和匹配的效率自然高
使用StringBuilder进行字符串拼接
使用String.valueOf来进行字符串转化
数组
使用System.arraycopy进行拷贝数组
集合转化为类型T数组时, 尽量传入空数组T[0]
集合转化为Object数组时, 尽量使用toArray()方法而非toArray(new Object[0])
集合
初始化集合时, 尽量指定大小, 减少扩容次数
尽量使用addAll()来批量拷贝
使用Arrays.adList()转化数组为列表
直接迭代需要使用的集合
不要用size()方法检测空, 用isEmpty方法检测, 因为某些size方法实现的时间复杂度可能是O(n)
尽量使用迭代遍历来代替for循环里get()
尽量使用HashSet判断值存在
避免先判断存在再获取, 因为会造成二次查找, 直接获取然后判断是否为空
异常
直接捕获各种异常, 而非instanceof
避免在循环中捕获, 在循环体外捕获可以提高执行效率
禁止使用异常控制业务流程, 比如 抛了异常就返回false
缓冲区
尽量重复使用同一缓冲区
使用缓冲流减少IO操作
线程
单线程中, 尽量使用非线程安全类
多线程中, 尽量使用线程安全类
尽量减少同步代码块范围
尽量合并为同一同步代码块
尽量使用线程池来减少线程开销