Effective Java 2.5——避免创建不必要的对象

来源:互联网 发布:windows7服务优化说明 编辑:程序博客网 时间:2024/05/15 02:17

第五条 避免创建不必要的对象

这个在高性能作业的时候显得尤为重要,因为反复创建不必要的对象无论在时间还是空间上都是造成极大的浪费。

下面我把书中介绍的几个反面例子给大家抄一下:
创建String对象

String s = new String("test");

这句话相信大家在学习java的时候书中应该也特意提到过不推荐这么写,因为会创造两个对象。“test”会在常量池里面有一个对象;因为new了一个对象,所以在JAVA堆里面也会有一个对象。这样子就多创建了一个Java堆的对象。

我们用一段代码来验证我们上面所说的分配现象:

public static void  main(String s[]){    String test1= new StringBuffer("1").append("1").toString();    System.out.println(test1.intern()==test1);    String test2 = new String("test");    String string3 = new StringBuffer("te").append("st").toString();    System.out.println(string3.intern()==string3);}

上述代码结果为:true false
String.intern()方法:如果常量池中有该String对象则返回常量池中对象,否则返回此String对象的引用。
test1由于是由StringBuffer使用append连接而来,这样写的话常量池里面会有“1”的对象,但是没有“11”。而在Java堆里面则是存放“11”这个String对象。所以test1.intern()只是返回test1对象的引用,结果为true。
接下来我们创建一个test的String对象,如果其没有在常量池创建对象,那么string3.intern()==string3)返回的也应该是true,但事实证明返回的是false,说明String test2 = new String(“test”);确实在常量池中建立了test这么一个String常量。

Java堆中对象的证明我想就没有必要了吧~~因为只要new了,必定会在堆里面分配一个对象。
所以说如果没有特殊的需求,我们就应该已

String test = "test";

来代替String test = new String("test");

静态工厂代替构造器

这个我们在第一条的时候就提过,这里就不展开说明了。大家可以回去看看。

重用已知不会被修改的对象

不好的代码:

class A {    int a;    public A(int i) {        i = a;    }    public boolean testA(int i) {        A defaultA = new A(0);        A a = new A(i);        return a.a>defaultA.a;    }}

这个方法的作用就是判断传入的值与基准对象defaultA .a进行比较。那么如果我们这样写,如果调用这个testA上万次,我们也会产生上万个defaultA 对象。
改进的方法:

class A {    private static final A defaultA;    static{        defaultA = new A(0);    }    int a;    public A(int i) {        i = a;    }    public boolean testA(int i) {        A a = new A(i);        return a.a>defaultA.a;    }}

这里定义了一个静态域,作用是只要调用A这个类就会自动初始化defaultA,而且为static final。保证不会重复创建defaultA对象。

小心自动装箱

Long l = 0;for(long i=0;i<10000;i++){    l+=i;}

大家找得着上述代码什么地方引起问题了吗?就因为吧long打错成Long,循环里面就多创建了10000个Long对象。自己写的时候千万要当心呦~

书中就列举了上述的几个引起创建不必要的重复对象的例子。不知大家记住了没

0 0
原创粉丝点击