1.6避免创建不必要的对象
1.6.1
一般来说,最好能重复利用单个对象而不是每次都创建一个一样的对象
public void eachData(){
for(int i=0;i<20;i++){
String charData=new String("hello world"); //这种写法是非常浪费内存的
//第一次创建两个对象,一个在栈上,一个在堆上。栈上对象存放着对堆上对象的引用。堆上对象是一个值(存在于常量池)
}
for(int i=0;i<20;i++){
String charData="hello world"; // 采用此种写法
//而是直接使用已经存在常量池的值
}
}
1.6.2
静态工厂方法Boolean.valueOf(String)几乎总是优选于构造器,注意构造器在java9中已经被遗弃了。对于一些创建成本比较高昂的对戏那个。建议重复利用它。而不是每次都创建它。
1.6.3
String.matches方法最容易查看一个字符串是否与正则表达式相匹配,但并不适合在注重性能的情形中重复使用。问题在于它在内部为正则表达式创建了一个Pattern实例,却只用了一次,之后就可以进行垃圾回收了。创建Pattern实例的成本很高,因为需要将正则表达式编译成有限状态机
以下代码
static boolean isRomanNumberal(String s){
return s.matches("^(?=.)M*(C[MD]D?C{0,3})(X[CL]|L?x{0,3})(I[XV]|V?I{0,3})$");
}
为了提升性能,应该显示的将正则表达式编译成一个Pattern实例(不可变的final),让它成为类初始化的一部分,并将它缓存起来。每次调用isRomanNumberal方法的时候就重用同一个实例
优化后的代码
public class RomanNumberal{
//此对象只会创建一次
private static final Pattern ROMAN=Pattern.compile("^(?=.)M*(C[MD]D?C{0,3})(X[CL]|L?x{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumberal(String s){
return ROMAN.matcher(s).matches();
}
}
1.6.4
自动装箱使得基本类型和装箱类型之间的差遍变的模糊起来,但是并没有完全消除。它们在性能上存在着比较明显的差别
以下代码
private static long sum(){
Long sum=0L;
for(long i=0;i<=Intger.MAX_VALUE;i++){
sum+=i;
}
return sum;
}
优化后的代码
private static long sum(){
long sum=0L; //采用基础数据类型的long。速度会比装箱的Long。此方法将快五六倍
for(long i=0;i<=Intger.MAX_VALUE;i++){
sum+=i;
}
return sum;
}
总结:要优先使用基本类型而不是装箱类型,要是当心无意识的自动装箱。
网友评论