对于JAVA的String在很长一段时间里都没有系统地去整理下,现在写个笔记,加深印象。
String在JAVA中不属于8个基本数据类型,这个在笔试面试的时候要小心,String是JAVA中的一个类,他有自己的构造器,可以new,比较特殊的地方在于String是常量,一旦被创建出来就无法改变。
举例说明
String str = "a";
str = "ab";
str = "a";
上面三句话实际上是产生了2个字符串对象,根据String的不可变特性,当str由a变为ab的时候,实际上并不是直接在str的内存地址上直接进行值修改,而是给了str另外一个值为ab的字符串对象的内存地址,因此a这个字符串还是存在的。
另外一个要知道的知识点是字符串对象的存储区域,要知道在JVM中字符串对象被创建出来后就会被放置在一个称为字符串池的内存区域,这个区域在JAVA的内存模型中属于静态内存区,还是以上面的代码为例说明,第一句话,实际上是JVM在字符串池中创建了一个值为a的字符串对象并将该对象的内存地址赋给了str的内存区域,这样的操作就称为引用;第二句话,JVM还是在字符串池中创建了一个值为ab的字符串对象,并赋给str的内存新的一个地址,也就是ab字符串对象的地址;第三句话,由于值为a的对象已经在池中存在了,因此JVM不会再创建新的对象,而是将之前就有的对象的地址赋给了str,JVM以此来提高字符串这种常用对象的复用性。
一开始的时候就讲到String也是有构造器的,也是可以new的,但是使用下面的代码
String str = new String("abc");
与直接赋字符串常量,实际的工作流程就不太一样了,JVM会在堆中开辟一块内存区域,然后将堆的地址赋给str的内存区域。因此就有了下面的经典考题
String str1 = "abc";
String str2 = new String("abc");
String str3 = new String("abc");
System.out.println(str1 == str2);//false
System.out.println(str1 == str3);//false
System.out.println(str2 == str3);//false
上面三句代码一共产生了几个String对象,答案应该是3个,在字符串池中1个,在堆中2个,并且所有的打印也应该都输出false,原因是他们的内存地址都不一样。
然后还有一个疑问的是那么对于字符串的+操作,到底产生了多少String对象呢,这里要考虑下面两种情况。
第一种情况是字符串常量连接,代码如下:
String str1 = "ab" + "cd";
String str2 = "abcd";
System.out.prinltn(str1 == str2);//true
你发现在整个字符串连接的表达式中出现的都是字符串常量,那么这种情况,在编译期他们就直接被合并为abcd这个字符串常量了,而不需要产生中间的ab和cd,因此只产生了一个字符串对象。所以打印的结果是true,str1和str2都是池中对象的引用。
第二种情况是字符串变量连接,代码如下:
String str1 = "ab";
String str2 = "cd";
String str3= str1 + str2;//new String("ab")+new String("cd")
String str4 = "abcd";
System.out.println(str3 == str4); // false
你发现在字符串连接的表达式中出现了字符串变量(只要是编译器不能直接确定值的都是变量,所以使用构造器生成的String也视为变量),这种情况,JVM会在堆中创建一个StringBuffer类,并使用ab的值作为这个StringBuffer类的初始化,然后调用StringBuffer的append方法,进行字符串追加,追加完毕后,在调用StringBuffer的toString方法在堆中创建一个String对象,并将该String对象的地址赋给str3的内存区域。所以上面的代码str1,str2,str4在池中创建了3个String对象,str3由于toString方法在堆中创建了一个String对象,由于+操作符在堆中创建了一个StringBuffer对象。所以最后的打印结果也就容易理解了,str3的值是堆中的String的地址,而str4是池中的String的地址,然后不一样。
最后是String中有个方法比较特殊,叫intern方法,当调用 intern 方法时,如果池已经包含一个等于此 String
对象的字符串(用 equals(Object)
方法确定),则返回池中的字符串。否则,将此 String
对象添加到池中(这里的添加是指在池中创建一个值相同的String对象,而原来的String对象还是被保留着的),并返回此 String
对象的引用。 所以看下下面代码理解下这个方法的意思。
String str1 = new String("abc");
System.out.println(str1 == str1.intern());//false
String str2 = "abc";
System.out.println(str2 == str1.intern());//true
另外补充一点是所有的字符串操作方法,如substring,concat等,都会在堆中产生一个新的String对象。所以现在对于常见的问一段代码中产生了多少字符串对象的问题应该都能够应对自如了。
然后,我们就可以开始介绍StringBuffer,由于String的不可变性,如果要对String进行追加或者裁减的操作会产生很多额外的String对象,所以我们推荐当需要进行大量的字符串操作的时候,使用StringBuffer来完成,因为StringBuffer是可变的。
StringBuffer sb="ab";
s.append("cd");
如上面实际上就只产生一个StringBuffer对象。
贴一个百度百科对StringBuffer的介绍,还是比较全面的 http://baike.baidu.com/view/1486261.htm
StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。
做个总结就是:单线程就用StringBuilder吧,多线程就用StringBuffer,要是你只是存取下数据String就可以了。
分享到:
相关推荐
String StringBuffer和StringBuilder 区别之源码解析 从源码角度简单对它们之间的区别进行了验证
String,StringBuffer,StringBuilder区别。几乎所有的应用开发都离不开操作字符串,理解字符串的设计和实现以及相关 工具如拼接类的使用,对写出高质量代码是非常有帮助的
String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别
StringBuffer:字符创变量 StringBuilder:字符创变量 从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
介绍了String、StringBuffer、StringBuilder的使用方法,以及理论知识
下面小编就为大家带来一篇浅谈java中String StringBuffer StringBuilder的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
String ,StringBuffer与StringBuilder的区别
简单的介绍了String、StringBuffer和StringBuilder的区别
String及StringBuffer和StringBuilder的区别
stringbuilder用法 String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String...
String、StringBuffer 和 StringBuilder 的区别 碎碎念 简单认识这三个对象 String StringBuffer StringBuilder 深入理解 String、StringBuilder、StringBuffer 从设计角度理解 String StringBuilder StringBuffer ...
string,stringbuffer,stringbuilder
string,stringBuffer,stringBuilder
java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间有什么区别呢?下面小编给大家总结了Java中String、StringBuffer、StringBuilder的区别详解,需要的朋友参考下吧
目录StringStringBuffer与StringBuilder总结 String ...StringBuffer与StringBuilder 这两者基本相似,都是可变字符串对象,主要区别为线程是否安全。 总结 最后,引用菜鸟教程下的总结以及相关评论: S
String,StringBuilder,StringBuffer
String、StringBuilder以及StringBuffer的区别
主要介绍了Java 中 String,StringBuffer 和 StringBuilder 的区别及用法的相关资料,需要的朋友可以参考下
Java中String,StringBuffer与StringBuilder的区别和用法。
StringBuilder三者之间的区别是很有必要的,很多面试面试官都会问到这个知识点。集合网络上很多牛人的各种经典分析的总结,花了两个小时概括总结得出了现在这个最全面、最详细、最精辟、最透彻的解答。 不管是菜鸟...