本文参考

本篇文章参考自《Effective Java》第三版第六条"Avoid creating unnecessary objects"

avoid creating unnecessary objects by using static factory methods in preference to constructors on immutable classes that provide both

若一个类同时提供了静态工厂方法和构造方法,尽量使用静态工厂方法,因为静态工厂方法"they are not required to create a new object each time they're invoked"

这在第一条"用静态工厂方法代替构造器"中已有提及,例如boolean的装箱类Boolean,它的valueOf()方法和构造器都能返回一个指定布尔值的实例,但是构造器会新创建一个对象,而valueOf()方法会返回类内已有的一个静态不可变实例

public static final Boolean FALSE = new Boolean(false);

注意,不要因此而时时避免创建对象,现代的JVM都能够很好地应对小对象的创建,并且创建额外的对象能够提高程序的清晰性和简化部分逻辑

On the contrary, the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementations. Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing

some object creations are much more expensive than others.If you're going to need such an "expensive object" repeatedly, it may be advisable to cache it for reuse

这往往不太容易发现,在某些类的方法被调用时,可能会产生另外一个中间的类实例,例如String.match()方法被调用时,会生成一个中间的Pattern类实例,最好将Pattern类实例缓存(如作为静态不可变字段),直接用Pattern类实例匹配正则表达式

as is often the case with lazy initialization, it would complicate the implementation with no measurable performance improvement

懒加载模式的代码实现往往会因为多线程访问而变得复杂,可能不会带来明显的性能提升,可以使用饿汉模式,在类加载时便对静态字段进行构建

prefer primitives to boxed primitives, and watch out for unintentional autoboxing

尽量使用基类型进行运算,因为装箱类型可能会有中间对象的创建和销毁,例如Long类型的加法运算

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

程序在for循环内构造了多余的2^31个多余的Long实例

avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight

只有在对象的创建十分昂贵时,才进行池化,例如数据库连接池,现代的JVM的垃圾回收器性能很容易就会超过轻量级对象池的性能

Generally speaking, however, maintaining your own object pools clutters your code, increases memory footprint, and harms performance. Modern JVM implementations have highly optimized garbage collectors that easily outperform such object pools on lightweight objects

consider the case of adapters, also known as views

视图是一种特殊的情况,例如Map接口的keySet方法返回该Map对象的Set 视图

Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

@Test
public void keySetTest() {

  Map<String, String> map = new HashMap<>(3);

  map.put("first key", "john");

  map.put("second key", "Sara");

  map.put("third key", "Mike");

  Set<String> set = map.keySet();

  for (String key : set) {

    System.out.println(key);
  }

  System.out.println("after remove the second key");

  map.remove("second key");

  for (String key : set) {

    System.out.println(key);
  }
}

最新文章

  1. NodeJS使用mysql
  2. Approaches to Vector Computation
  3. 【读书笔记】iOS-自动释放池
  4. update-alternatives命令
  5. Sleep v.s. sleep
  6. What is a heap?--reference
  7. android studio布局文件/XML怎么代码补全
  8. EditText 限制输入整数和小数 的位数
  9. winsock 编程(简单客户&amp;服务端通信实现)
  10. 第四百一十三节,python面向对象,组合、类创建的本质、依赖注入
  11. lambda group by 的用法
  12. centos7系统下hostname解析
  13. KMP算法——从入门到懵逼到了解
  14. (转)Awesome PyTorch List
  15. git,版本控制教程
  16. Linxu
  17. CH5105 Cookies【贪心】【线性dp】
  18. FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器
  19. Memcached: 目录
  20. linux 命令学习-网络相关配置

热门文章

  1. 案例三:shell统计ip访问情况并分析访问日志
  2. 【C#】COM线程模型-套间 ApartmentState
  3. 【C#表达式树 七】 反射在表达式树中的应用 ListInitExpression
  4. selenium+python自动化102-登录页面滑动解锁(ActionChains)
  5. tensorflow_keras_预训练模型_Applications接口的使用
  6. 第五篇- 抖音的强大对手来了,用Flutter手撸一个抖音国际版,看看有多炫
  7. HTML的表格标签,列表标签,表单标签,HTML5有哪些新特性
  8. 面试官:我们来聊一聊Redis吧,你了解多少就答多少
  9. 全面解读 AWS Private 5G 的革新理念
  10. 2022年官网下安装MAVEN最全版与官网查阅方法