如何避免无意间创建多余对象

简介: 6 避免创建不必要的对象从字面意思上来看,大家肯定都知道创建不必要的对象是错误的做法。但这一节其实主要是提醒我们避免无意识的创建不必要对象的代码写法。

6 避免创建不必要的对象


从字面意思上来看,大家肯定都知道创建不必要的对象是错误的做法。但这一节其实主要是提醒我们避免无意识的创建不必要对象的代码写法。


例1:


String s = new String("abc");


是错误的写法,正确的写法应该是:


String s = "abc";


原因是第一种写法每次被执行的时候都会创建一个新的String实例,但这些全都是重复的!



例2:


我们要优先使用静态工厂方法而不是构造器来避免创建不必要的对象,如Boolean.valueOf(String)总是要优先于构造器Boolean(String)使用。因为构造器每次被调用都会创建一个新对象,静态工厂不这样。



例3:


创建成本昂贵的对象时,应该将其缓存起来。


例如正则表达式匹配的代码中,String.matches方法内部创建了一个Pattern实例,这个创建的成本很高,因为需要将正则表达式编译成有限状态机,所以应该将其缓存起来:

public class RomanNumerals {
  private static final Pattern ID = Pattern.compile("^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$");
  static boolean isRomanNumeral(String s){
    return ID.matcher(s).matches();
  }
}


这样一来,每次调用isRomanNumeral时都会重用同一个ID实例



例4:


上面的Pattern实例是不变的,但在某些场景下实例是可变的,这时就可以考虑适配器。适配器是这样一个对象:它将功能委托给一个后备对象,为后备对象提供一个替代前面功能的接口。


例如Map接口的KeySet方法,每次调用返回的都是同一个Set实例,虽然Set实例是可变的,但其中一个变化时其他的也会跟着变,因为他们本身就是一个。



例5:


优先使用基本类型而不是装箱类型,原因在于下面这个例子:


private static long sum(){
  Long sum = 0L;
  for(long i = 0; i <= Integer.MAX_VALUE; i ++)
    sum += i;
  return sum;
}

这段程序执行起来没有任何问题,但实际情况会慢一点,因为sum的类型是Long而不是long,所以程序构造了大约2^31个Long实例。


这一点在我记忆中和工作里的要求不一致,为此我专门去翻阅了阿里巴巴Java开发手册,里面是这样描写的:


28.png

可见公司在这个问题的考虑上是业务优先了,所以小伙伴们可以斟酌使用时的取舍,我个人还是推荐使用包装类型的。


避免一个误区:

不要看完这一章节就陷入了创建对象的代价非常昂贵的逻辑怪圈里去了,反之维护自己的对象池来避免创建对象是一种错误的做法。因为现代JVM的实现里有高度优化的垃圾收集器,其性能很容易就超过了轻量级对象池的性能。


一个正确的示例是数据库连接池,因为建立一个数据库的连接是非常昂贵的。


相关文章
|
机器学习/深度学习 存储 传感器
【路径规划】基于Dijkstra算法求解机器人栅格地图路径规划及避障附Matlab代码
【路径规划】基于Dijkstra算法求解机器人栅格地图路径规划及避障附Matlab代码
|
存储 Java 应用服务中间件
Session基本使用及原理和使用细节
Session基本使用及原理和使用细节
305 0
|
JavaScript 前端开发 搜索推荐
【庖丁解牛】vue-element-admin前端CRUD通用操作组件详解
【庖丁解牛】vue-element-admin前端CRUD通用操作组件详解
1739 0
【庖丁解牛】vue-element-admin前端CRUD通用操作组件详解
|
C++
05 C++ - 作用域运算符(::)
05 C++ - 作用域运算符(::)
128 0
|
11月前
|
存储 Java Android开发
Android|记一个导致 logback 无法输出日志的问题
在给一个 Android 项目添加 logback 日志框架时,遇到一个导致无法正常输出日志的问题,这里记录一下。
224 2
|
前端开发 Python
【前端验证】通用型顺序比对的uvm scoreboard组件编写
【前端验证】通用型顺序比对的uvm scoreboard组件编写
473 0
EDM营销平台有哪些?Top5平台分析
探索五大热门EDM营销平台:蜂邮EDM以其丰富功能备受喜爱;Constant Contact以用户友好体验著称;Sendinblue结合短信营销与广告管理,适合中小企业;GetResponse提供营销自动化解决方案,适合各类企业;AokSend以其历史底蕴和分析工具吸引用户。各平台特色各异,企业可根据需求选择。
|
缓存 前端开发 JavaScript
前端面试必须掌握的手写题:进阶篇
前端面试必须掌握的手写题:进阶篇
185 0
|
存储 SQL 算法
LeetCode 题目 65:有效数字(Valid Number)【python】
LeetCode 题目 65:有效数字(Valid Number)【python】
|
SQL Java 数据库连接
springboot整合mybatis-plus详解
springboot整合mybatis-plus详解
622 0