在代码Review的时候,也许你老大会告诉你,字符串创建要放到循环之外。
for(int i = 0; i < length; i++) {
String s = new String(i);
}
为什么呢?
因为在循环的时候,创建了太多的临时对象。每一次循环,都需要new String()
,并赋值给新的对象s
。我们可以作如下改进:
String s;
for(int i = 0; i < length; i++) {
s = String.valueOf(i);
}
这样避免每次循环都要创建对象字符串s
。
在Java
中还有很多其他的地方都有这些小细节:
1. 还记得【Effective Java】条1:考虑用静态工厂方法代替构造器1中给出的Boolean
案例吗?
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
相比于new Boolean(String s)
构造方法,valueOf
方法返回的TRUE
和FALSE
都是内置的对象,并不是和构造方法一样,每调用一次就会新建个Boolean
对象。
==所以,以后看到类同时有构造函数和静态构造方法时,查看下静态构造方法的实现,也许可以节省很多资源。==
-
HashMap
的keySet
方法,返回的是Map
中所有key
的Set
形式。查看下代码,你会发现这里的Set
其实就是AbstractMap
中的成员变量。 -
Java
中还有种情形下会隐式的创建不必要的对象。大家都知道int
和Integer
,long
和Long
可以相互转换(自动装箱和拆箱)。譬如:
public static void main(String[] args) {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
这段代码没有问题,但是中间隐藏了创建笔不要的对象。由于sum
声明为Long
类型,所以每次循环操作都需要将sum
转为Long
类型,增加了对象的创建。其实,只需要将Long sum = 0L
改为long sum = 0L
即可。
==所以,在程序开发中,尽量避免使用基本类型和装箱类型的交互操作,防止创建不必要的对象。==
说了这么多,其实不是让大家在开发中避免创建对象。其实对于绝大部分的对象都是可以直接创建,只是在循环、装箱操作、以及对象创建非常耗时等过程中需要注意,避免浪费不必要浪费的资源。