一、String的JVM内存分配测试与分析 
        
        String a="a";
        String b="b";
        String c="ab";
        String d="ab";
        String e=a+b;
        String f = "a" + "b";
        final String p = "a";
        final String q = "b";
        String m = p + q;
        String n = p + "b";
        String str1 = new String("ab");
        String str2 = new String("ab");

        System.out.println("c==d?" + (c==d));
        System.out.println("d==e?" + (d==e));
        System.out.println("c==f?" + (c==f));
        System.out.println("c==m?" + (c==m));
        System.out.println("c==n?" + (c==n));
        System.out.println("d==str1?" + (d==str1));
        System.out.println("str1==str2?" + (str1==str2));
        System.out.println("e==str1?" + (e==str1));

输出结果:

c==d?true
d==e?false
c==f?true
c==m?true
c==n?true
d==str1?false
str1==str2?false
e==str1?false

程序中用来存放数据的内存分为四块

1、全局区(静态区)(static)

2、文字常量区 :常量字符串就是放在这块区域,即是我们常说起的常量池。

3、栈区(stack):存放函数的参数值,局部变量的值等。

4、堆区(heap) : 存放对象



当我们定义字符串

String a = "a";

a在栈区,“a”是字符串常量,在常量池中

String b = "b";

b在栈区,“b”在常量池

String c="ab";

c在栈区,“ab”在常量池

String d="ab";

d在栈区,这个时候常量池里已经有"ab",所以直接使用已经有的那个“ab”

所以这个时候c和d都指向的常量池里面的同一个“ab”

String e=a+b;

e在栈区,a+b实际上产生了一个新的String对象,既然是String对象,所以结果“ab”放在堆区中,即e指向的是堆里的“ab”

这样的情况下,c==d为true,c==e为false

////////////////////////////////////

另外,如果定义的是字符串对象

String str1 = new String("ab");

str1在栈区,创建的“ab”字符串对象在堆区

String str2 = new String("ab");

str2在栈区,又创建的一个新的“ab”对象也在堆区,不过和刚才的“ab”不是同一个。

相当于堆区中有两个字符串对象,不过正好内容都是“ab”而已。

所以str1==str2为false



常量池里面放着的常量字符串可以重复使用,但是必须是你直接使用的该字符串,像a+b这种形式虽然得到的结果是“ab”,但并不是使用的字符串常量“ab”。

关于String e=a+b,还有一种说法是经过编译器优化之后,结果为“ab”,则编译器直接从常量池中拿出“ab”常量,将引用赋值给e。我使用的JDK是1.6.0_34,得出的结果是d==e?false,说明这个版本的JVM没有进行上述的编译器优化。
(后期修正:对于String e = a + b;编译器是存在优化的。但是编译器的优化是在编译期,由于a和b都是变量字符串,在编译期无法确定其具体值,故编译期无法优化。如果a和b都使用了final修饰并且赋了初始值,即a和b是有初始值的常量字符串,则在编译期就能确定其值,编译器就会将e的值优化为"ab"。关于JVM常量池和字符串优化更详细的解释,请参考我的另一篇博文:String放入运行时常量池的时机与String.intern()方法解惑.

以上绝大部分内容摘抄了http://blog.sina.com.cn/s/blog_4b622a8e0100c296.html处的分析。



二、StringBuilder&StringBuffer

看了以下两个帖子,都写得挺详细的,大家可以去看看:

http://blog.csdn.net/kingzone_2008/article/details/9220691

http://www.cnblogs.com/dolphin0520/p/3778589.html


看了看源码,自己的一点理解:

1)
StringBuffer是线程安全的,StringBuilder是非安全的,在大部分情况下我们都不需要考虑多线程问题,所以用StringBuilder效率会高一点点,但当需要多线程的时候,就要使用StringBuffer了。以下英文是StringBuilder源码里的注释,也给出了使用建议。

This class provides an API compatible

 * with <code>StringBuffer</code>, but with no guarantee of synchronization.

 * This class is designed for use as a drop-in replacement for

 * <code>StringBuffer</code> in places where the string buffer was being

 * used by a single thread (as is generally the case).   Where possible,

 * it is recommended that this class be used in preference to

 * <code>StringBuffer</code> as it will be faster under most implementations.
2)
        StringBuilder sb  = new StringBuilder();
        sb.append( "AAAA");
        String appendStr = null;
        sb.append(appendStr);
        sb.append( "BBBB");
        System. out.println( "sb:" +
sb.toString());

         控制台输出结果:sb:AAAAnullBBBB
         这是因为对于append方法,当参数为null时,StringBuilder&StringBuffer中的处理是默认将“null”字符串加入sb的后面。 


String&StringBuilder&StringBuffer总结的更多相关文章

  1. 深入源码剖析String,StringBuilder,StringBuffer

    [String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...

  2. String, StringBuilder, StringBuffer问题

    1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...

  3. String StringBuilder StringBuffer区别

    String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...

  4. difference among String,StringBuilder,StringBuffer

    difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...

  5. JDK源码分析系列---String,StringBuilder,StringBuffer

    JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...

  6. java中String StringBuilder StringBuffer比较和效率(性能)测试

    string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...

  7. string,stringbuilder,stringbuffer用法

    总结:1.如果要操作少量的数据用 = String   ==================================>字符串常量2.单线程操作字符串缓冲区 下操作大量数据 = Strin ...

  8. java中string stringbuilder stringbuffer 的区别

    1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...

  9. String,StringBuilder,StringBuffer

    (转:http://blog.csdn.net/rmn190/article/details/1492013)   String 字符串常量StringBuffer 字符串变量(线程安全)String ...

  10. String Stringbuilder Stringbuffer的区别

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

随机推荐

  1. [BZOJ]2594 水管局长数据加强版(Wc2006)

    失踪人口回归. LCT一直是小C的弱项,特别是这种维护链的信息的,写挂了就会调代码调到心态爆炸. 不过还好这一次的模板练习没有出现太多的意外. Description SC省MY市有着庞大的地下水管网 ...

  2. 用Qemu运行/调试arm linux【转】

    转自:https://blog.csdn.net/absurd/article/details/78984244 用Qemu运行/调试arm linux,这事情干过好几次了,久了就忘记了,每次都要重新 ...

  3. IDF实验室-CTF训练营-牛刀小试CTF

    自从开始玩CTF后,发现这个游戏还是比较有意思,发现了一个练习场地IDF实验室:http://ctf.idf.cn/ 刷刷里面的题目,今天完成了其中的牛刀小试,分享一下解题思路: 1. 被改错的密码 ...

  4. Java Servlet 笔记3

    Servlet 表单数据 很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序.浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法. 1. ...

  5. JS 中判断空值 undefined 和 null

    1.JS 中如何判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正 ...

  6. Vue生命周期-手动挂载理解

    改前端遇到个bug,console能够输出值,但是前端不能显示. 我简直一脸懵逼,vue的问题?网络的问题?浏览器的缓存问题? 公司网络,所以直接排除网络问题. 浏览器缓存,试了下确实一定概率可以显示 ...

  7. 48. Rotate Image(中等)

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  8. 讨论过后而引发对EF 6.x和EF Core查询缓存的思考

    前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...

  9. 将Python当作计算器

    在交互模式中,最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个桌面计算器,很方便的用于连续计算.例如: >>> price = 1.25 #声明变量price >&g ...

  10. JS的replace默认只替换第一个匹配项

    1. JS的replace默认只替换第一个匹配项. 解决方法: 使用正则表达式进行匹配替换[   ①.replace(new RegExp(②,"g") ,③);   ] ①:包含 ...