您的位置:首页 > 产品设计 > UI/UE

面试必备:String,StringBuffer,StringBuilder区别

2016-01-30 10:21 267 查看
首先说一下,这三个类都是用来处理字符串的,

StringBuilder是JavaSE5之后引入的,用来替代StringBuffer,

StringBuffer相对于StringBuilder线程是安全的,所以开销会大一些

StringBuilder线程不安全,字符串操作会快一些。

线程安全不安全概念是什么呢??

卖票例子大家都听过吧,假设共有50张票,如果让A,B,C三人同时卖票,如果是线程不安全的会是怎么样的呢?

假设A卖出了30张,但是此时票的数量还没来得及修改B就开始卖票了,这就会导致一个问题,B所获取到的票的余量就会是50.这就导致了不同步的问题。也就是说如果是多人同时操作一个对象,如果不加同步锁,就会造成线程不安全的对象。

至于与String的区别,体现在String字符串使用加号的时候:

String str = "a"+"b"+"c"+"d";


在使用上述方式创建字符串时,每使用“+”号连接一个字符串就会创建一个新的String的对象,这会造成内存极大的浪费

对于这个创建对象的问题需要详细分析:(参考http://www.iteye.com/topic/634530)

我主要关注的是栈,堆和常量池

1,例如,创建一个对象

String str = "ch";


此时会在常量池中创建一个ch对象,并且会在栈中创建一个对象的引用str。也就是说这句代码只创建了一个对象。
2,但如果是

String str1 = "ss" + "hh";就会在栈中创建一个引用str1,在常量池中创建三个对象:ss对象,hh对象,和sshh对象,这是因为,
程序首先会去常量池中寻找是否有ss字符串对象,不存在,则创建ss对象。

hh对象同一个道理

因为字符创属于不可变的对象,所以如果想要获取到sshh对象只能是去在常量池再次创建一个sshh对象

3 如果是使用new创建字符串

String str2 = new String("tt");


首先程序会在堆中创建一个new String对象,因为在new的过程中需要到“tt”,所以会去常量池中去寻找tt对象,如果对象不存在,则要去创建。
所以这句代码是在常量池创建了一个对象:tt,在堆中创建了一个对象new String,在栈中创建了对象的引用str2

4,如果是用StringBuilder:

StringBuilder str3 = "pp";

StringBuilder str4 = str3.append("ll");

程序首先要在常量池中去创建pp这个对象,在append时在常量池中创建ll这个对象,在这里只创建了两个对象,在栈中创建了3个引用。这是因为StringBuilder分配的空间是可变的,所以在append之时,是直接把ll对象添加到pp所在的存储区域中。

以上所有的分析都是假设在创建字符串对象时常量池中不存在对应字符串的情况下得出的结果,如果在常量池中有对应的字符串存在则不再需要创建对象

总结:

对象存在的位置是在堆中(new出来的),常量池中(“”,直接定义出来的)

对象的引用存在栈中

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: