String和StringBuffer有什么区别?
1、String对象是不可变的,如果一旦修改了String对象的值,那么会隐性重新创建一个新的String对象并释放原来的对象。
而StringBuffer类是可修改的,如果想要在原字符串上添加,只要使用append方法就可以了,非常方便。
StringBuffer类操作字符串非常方便。
2、String类的性能远不如StringBuffer类。
StringBuffer类不能和String类一样,直接赋值。比如 StringBuffer sb = “ssss”;就会报错。
创建StringBuffer类对象:StringBuffer sb = new StringBuffer(“sss”);是先生成一个(长度为字符串长度+16)StringBuffer,
然后再通过append方法添加,源码里面有写到。
3.String重写了equals和hashcode方法,而StringBuffer 没有重写。
把StringBuffer对象存储进java集合类时会出现问题。
StringBuffer和StringBuilder的区别?
StringBuffer是线程安全的,StringBuilder是线程不安全的。两者单代码几乎一样,就是StringBuffer有synchronized关键字,所以
StringBuffer效率低一些。synchronized可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。
jvm的方法区有个常量池,常量池中的数据是那些在编译期间被确定的,并被保存在已编译的.class文件中的数据。除了八种基本的数据类型,还有String及其数组的常量值,还有一些文本形式出现符合引用。
final boolean b= true; final char c ='c';final String str = "123",可以拆开来看
1、true、c、123,这些等号右边的指的是编译期间可以被确定的内容,都被维护在常量池中
2、b、c、str这些等号左边第一个出现的指的是一个引用,引用的内容是等号右边数据在常量池中的地址
3、boolean、char、String这些是引用的类型
String s1 = "123";
String s2 = "123";
System.out.println(s1==s2);结果为true:因为java有一个常量池,在编译的时候,s1的值“123”会放到常量池去。然后当定义s2的时候就会去常量池找是否有相同的,结果发现存在相同的,于是s2也指向了"123",s1和s2指向同一个对象。因为==比较的是他们的地址,所以是true;
对于Java虚拟机的解释器每遇到一个new关键字,都会在堆内存中开辟一块内存来存放一个String对象,所以str2、str3指向的堆内存中虽然存储的是相等的"234",但是由于是两块不同的堆内存,因此str2 == str3返回的仍然是false,网上找到一张图表示一下这个概念:
String s1 = "123";
String s2 = new String("123");
System.out.println(s1==s2);结果就为false 因为s2是new了一个String,会在堆内存开辟一块空间。那么两个就不是同一个对象了,所以==来比较地址肯定是不一样的,所以
就是false。如果这个时候加上一句s2 = s2.intern();那么结果就是true了。
Java查找常量池中是否有相同字符串常量,如果有,则返回其的引用, 如果没有,则在常量池中增加一个等于"123"的字符串并返回它的引用。在这里能找到常量池中存在“123”,
那么s2指向了常量池中的“123”,和s1相同。