String类详解

1、创建的字符串变量在内存中的区别

两者看似都是创建了一个字符串对象,但在内存中确是各有各的想法。

String str1= “abc”;在编译阶段就会在内存中创建, 在编译期,JVM会去常量池来查找是否存在“abc”,如果不存在,就在常量池中开辟一个空间来存储“abc”;如果存在,就不用新开辟空间。然后在栈内存中开辟一个名字为str1的空间,来存储“abc”在常量池中的地址值。

String str2 = new String(“abc”) ;在编译阶段JVM先去常量池中查找是否存在“abc”,如果过不存在,则在常量池中开辟一个空间存储“abc”。在运行时期,通过String类的构造器在堆内存中new了一个空间,然后将String池中的“abc”复制一份存放到该堆空间中,在栈中开辟名字为str2的空间,存放堆中new出来的这个String对象的地址值。
也就是说,前者在初始化的时候可能创建了一个对象,也可能一个对象也没有创建;后者因为new关键字,至少在内存中创建了一个对象,也有可能是两个对象。

String str1 = new String(“ABC”);
String str2 = new String(“ABC”);
System.out.println(str1.equals(str2)); // true 比较的值
System.out.println(str1 == str2); // false 比较的是内存地址。

String str3 = “ABC”
String str4 = “ABC”
String str5 = “AB”+“C”;
System.out.println(str3 == str4); //true 在string池中都是一个内存地址被分配给str3,str4,str5
System.out.println(str3 == str5); //true

String str6 = “AB”;
String str7 = str6 + “C”;
System.out.println(str3 == str7); //false

str6在编译的时候已经确认为string池的对象。
str7在编译的时候不能确认,故str7是一个引用变量。
str6+"C"的过程是创建了一个StringBuffer对象,然后用StringBuffer对象执行append方法追加,最后再转成String类型,也就是str7是放在heap里面的对象,str6是放在String常量池里的。两个的内存地址不一样。故结果为false。

2、两个方面

1)性能效率

String类被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。例如:

String str = “hello";

str = str + "world“;

所以当上文str指向了一个String对象(内容为“hello”),然后对str进行“+”操作,str原来指向的对象并没有变,而是str又指向了另外一个对象(“hello world”),原来的对象还在内存中。

由此也可以看出,频繁的对String对象进行修改,会造成很大的内存开销。此时应该用StringBuffer或StringBuilder来代替String。

而new String()更加不适合,因为每一次创建对象都会调用构造器在堆中产生新的对象,性能低下且内存更加浪费。
2)安全性

对象都是只读的,所以多线程并发访问也不会有任何问题。

由于不可变,用来存储数据也是极为安全的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值