1.String的三大特性
1.String是被final修饰的类,是不能被继承的
2.String是可序列化和可比较的
3.String底层是通过char类型的数据实现的,并且被final修饰,所以字符串在创建之后就不能被修改,具有不可变性。
2.深入理解String的不可变性
在面试的时候,面试官总会问我们,”String是真的不可变的吗?它是怎么一个不可变的呢?“你怎么回答?下面明怀我将引入jvm存储方面的东西来帮助你解答一下这些疑难。
String s1=“hi”;
Stirng s2=“hi”;
s1=“hello”
这个时候你觉得会输出什么样的东西呢?那就是s1输出的是ok,但是你了解它的内存结构吗?
它的字符串的值是存放在方法区中的常量池里面,栈中存放的就是对应的字符串s1和s2,所以,假如说你为s1赋予一个新的值的时候,那么方法区中将会开辟一个新的区域作为地址,然后将s1指向这个地址。这么说你应该懂了吧?
2.1修改
假如你要对字符串进行修改的时候,它也不会在原来的地方进行赋值,而是重新分配新的内存地址,反正你记住就行了,只要是在常量池中不存在的字符串,它都会进行分配区域存放。
3.String实例化的两种方式
- String str=“abc”;
- String str=new String"(“abc”)
在这里,存放他们的区域无非就是栈、堆、常量池
4.StringBuffer与StringBuilder
说到这两个,其实他们和String唯一的共同点就是他们底层都是char数组来完成的,当他们存储的长度超过16之后,就会产生对应的对应的扩容,其实StringBuffer的扩容也很简单,那就是创建一个新的char数组,将现有的容量扩大一倍加上2,如果还是不够大的话则直接等于需要扩容的大小。
相同点:
1.他们都是继承自AbstractStringBuilder
不同点:
1.StringBuilder是线程不安全的,不适合用于多线程
2.但是StringBuffer是线程安全的,适用于多线程,因为在每个方法前面都加上了synchronized
4.1如何选择二者
对于如何选择二者,我想说的就是,当你不是处于多线程的情况下,可以尽量考虑StringBuilder,因为这样效率更高,不用考虑锁,但是当你处于多线程的环境下时,可以尽量考虑StringBuffer,因为它是线程安全的。
面试中:
1.String对象一旦创建,其值是不能进行修改的,如果要修改,这个时候需要开辟新的空间来存储修改之后的对象;而StringBuffer和StringBuilder的值是可以修改的,他们都有相同的方法。
等等…
5.总结
总的来说,String、StringBuffer、StringBuilder都有设计他们的理由,我们只需要搞懂他们的特点就可以了,学习也是一样,你不需要每天走多远的路,你只需要坚持就好了,相信自己,一定能够变得更加优秀,加油!