String 类是不可变类,也就是说 String 对象声明后,将不可修改
public class StringTest01 {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
s1=s1 + s2; //ab
//new String(“a”);
System.out.println(s1);
}
}
String
对象赋值后不能再修改,这就是不可变对象,如果对字符串修改,那么将会创建新的对象 。
注意:只要采用双引号赋值字符串,那么在编译期将会放到方法区中的字符串的常量池里,如果是运行时对字符串相加或相减会放到堆中(放之前会先验证方法区中是否含有相同的字符串常量,如果存在,把地址返回,如果不存在,先将字符串常量放到池中,然后再返回该对象的地址)
String s1 = “abc”和 String s2 = new String(“abc”)
public class StringTest02 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println("s1==s2, " + (s1==s2));
System.out.println("s2==s3, " + (s2==s3));
System.out.println("s2 equlas s3," + (s2.equals(s3)));
}
}
如果是采用双引号引起来的字符串常量,首先会到常量池中去查找,如果存在就不再分配,
如果不存在就分配,常量池中的数据是在编译期赋值的,也就是生成
class
文件时就把它
放到常量池里了,所以
s1
和
s2
都指向常量池中的同一个字符串“
abc
”
关于
s3
,
s3
采用的是
new
的方式,在
new
的时候存在双引号,所以他会到常量区中查找
“
abc
”,而常量区中存在“
abc
”,所以常量区中将不再放置字符串,而
new
关键字会在
堆中分配内存,所以在堆中会创建一个对象
abc
,
s3
会指向
abc
如果比较
s2
和
s3
的值必须采用
equals
,
String
已经对
eqauls
方法进行了覆盖
注意事项
使用 String 时,不建议使用 new 关键字,因为使用 new 会创建两个对象
因为
String
是不可变对象,如果多个字符串进行拼接,将会形成多个对象,这样可能会造成内存溢出,会给垃圾回收带来工作量
String、StringBuffer与StringBuilder
参考:https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303