读书人

深入Java核心 Java内存储器分配原理精

发布时间: 2012-12-22 12:05:05 作者: rapoo

深入Java核心 Java内存分配原理精讲---3

String常量池问题的几个例子

  下面是几个常见例子的比较分析和理解:

            就等价于String s = "abc";??
            String? a? =? "a";??
            String? b? =? "b";??
            String? c? =? "c";??
            String? s? =?? a? +? b? +? c;?

            这个就不一样了,最终结果等于:

          1. StringBuffer?temp?=?new?StringBuffer();??? ? temp.append(a).append(b).append(c);??? ?
          2. String?s?=?temp.toString();?

            由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:

          1. public?class?Test?{ ? public?static?void?main(String?args[])?{ ?
          2. String?s?=?null; ? for(int?i?=?0;?i?<?100;?i++)?{ ?
          3. s?+=?"a"; ? } ?
          4. } ? }?

            每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行 append操作。

            String对象的intern方法理解和分析:

          1. public?class?Test4?{ ? private?static?String?a?=?"ab";? ?
          2. public?static?void?main(String[]?args){ ? String?s1?=?"a"; ?
          3. String?s2?=?"b"; ? String?s?=?s1?+?s2; ?
          4. System.out.println(s?==?a);//false ? System.out.println(s.intern()?==?a);//true?? ?
          5. } ? }?

            这里用到JAVA里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所 以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在常量池中的地址值,因为a的值存储在常量池中,故s.intern和a的值相等。

            总结

            栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容

            堆中存放使用new关键字创建的对象.

            字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。

          1 楼 eriol 2011-01-10 写的不错!

读书人网 >编程

热点推荐