Java避免创建不必要的对象

最近看到了《Effective Java》这本书,这本书包含的内容非常丰富,这本书我就不多介绍了,只能默默的说一句,作为一名java开发错过了这本书难免会成为一个小遗憾,所以还是建议有时间的小伙伴能够去看看这本书,时间挤挤总还是有的。这本书介绍的很多东西我现在也还看不太明白,很多东西我们在平时的开发中也不见得会用上,所以我不会每个东西都拿来详细解释一遍,只会从中抽取我们平时开发中比较实用的,以及小Alan这个小菜鸟能够看懂的部分,至于一些不实用的以及比较高深的部分那就只能随着小Alan的工作经历和深入理解再慢慢的整理出来给自己也给部分觉得有用的朋友理清思路。

《Effective Java中文版 第2版》.(Joshua Bloch)(高清pdf)+英文版+源代码 

《Effective Java 》第5条:避免创建不必要的对象

我们把原文拆分成几部分来理解,实现一个一个的小目标,最后来完全理解这一块的内容。

第一部分:一般来说,最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。重用方式既快速,又流行。如果对象是不可变的,它就始终可以被重用。

反面例子:

String s = new String("啪啪啪");  //Don't do this!

该语句每次被执行的时候都创建一个新的String实例,但是这些创建对象的动作全都是不必要的。传递给String构造器的参数("啪啪啪")本身就是一个String实例,功能方面等同于构造器创建的所有对象。如果这种用法是在一个循环中,或是在一个被频繁调用的方法中,就会创建成千上万不必要的String实例。

改进版本:

String s = "啪啪啪";

这个版本只用了一个String实例,而不是每次执行的时候都创建一个新的String实例。而且,它可以保证,对于所有在同一台虚拟机中运行的代码,只要它们包含相同的字符串字面常量,该对象就会被重用。

扩展思路:①在Java1.7中运行,Java会在方法区运行时常量池中记录首次出现的实例,也就是说会在常量池中保存"啪啪啪",那么当你下次调用String s = "啪啪啪";的时候,Java会直接返回这个对象的引用,而不会去重新创建一个新的对象,这样就节省了内存的开销,也可以放心的在循环中去使用,也不怕在方法中被频繁的调用。String s = new String("啪啪啪");实际上创建了两个对象,一个存放在堆中,一个就是保存在常量池中的"啪啪啪",s只是对象的引用保存在栈中,而String s = "啪啪啪";只会创建一个对象保存在常量池中,然后保存一个对象的引用在栈中就ok了(对Java虚拟机理解不是很深入,理解有误请指出,万分感谢)。

第二部分:对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。例如,静态工厂方法Boolean.valueOf(String)几乎总是优先于构造器Boolean(String)。构造器在每次被调用的时候都会创建一个新的对象,而静态工厂方法则从来不要求这样做,实际上也不会这样做。

扩展思路:

1 package com.czgo.effective; 2 3 /** 4 * 用valueOf()静态工厂方法代替构造器 5 * @author AlanLee 6 * @version 2016/12/01 7 * 8 */ 9 public class Test { 10 11 public static void main(String[] args) { 12 // 使用带参构造器 13 Integer a1 = new Integer("1"); 14 Integer a2 = new Integer("1"); 15 16 //使用valueOf()静态工厂方法 17 Integer a3 = Integer.valueOf("1"); 18 Integer a4 = Integer.valueOf("1"); 19 20 //结果为false,因为创建了不同的对象 21 System.out.println(a1 == a2); 22 23 //结果为true,因为不会新建对象 24 System.out.println(a3 == a4); 25 } 26 27 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5622a5ef41fdd20aa40230640a7dde28.html