c++ string replace_String是不可变的

什么是String是不可变的

      String是引用类型,String变量储存一个地址,地址指向内存堆中的String对象。当我们说变量不可变,有两种不可变性:

  1. 变量储存的地址不可变;

  2. 地址指向的对象内容不可变。

    adef91cf3caa20aeb0b0ae8ed6c5d106.png

String的不可变指的是哪一种?下面用例子来看。

       通常有人在疑问String不可变时,会举这样的例子:我们平时不都像下面这样在“修改”String字符串吗:

String s = "hello,world";
s = "Hello,coder";
System.out.println(s); //Hello,coder

我认为这只是一个语义上的误导。赋值操作符=通常作用于基本数据类型时,确是修改变量的值。所以在这里让人误以为也是修改了变量的内容。但是对于引用类型String,s="Hello,coder"的实际作用是将变量s指向另一个内容为Hello,coder的新的对象。

       所以,对于String不可变性的结论显而易见了:String变量指向的地址是可变的,他的不可变性当然说的是第二种——地址指向的对象内容不可变。

纵览String的方法,String类确实没有提供能从String外部修改对象的方法。我们熟悉的replace,substring等等方法都要返回一个String,其实都是在返回一个新的对象,而没有修改原有的对象。

9eabb81963b9ce1128721b4940c84fbf.png

 String的不可变性是如何保证的

JDK源码中,存放String内容的实际上是char数组,这个数组是final类型的,一经初始化就不能改变。

 /** The value is used for character storage. */private final char value[];

       但是,char数组是引用类型,final类型只能保证value的地址不可变,不能保证value数组的内容不能变化。即完全可以通过以下方式改变value的内容:

final char[] value = {'a','b','c'};value[0] = 'd';

       所以,重点是字符数组为private访问权限,所以只有SUN的工程师可以拿到这个字符数组。而SUN的工程师在所有方法中都没有改变该字符数组的值。另外,String被定义为Final类型,也防止了通过继承之后破坏不可变性。

dd4a50fba4f33843e400d5afa0f2701d.png

String对象的不可变性的优点

       保证多线程安全:同一个String可以被多个线程同时使用,不需要考虑同步问题,因为该类的值无法被改变。String被线程使用时只可以读,不可以写,又因为多个线程可以同时读,不可同时写或者同时读写,因此String可以被多个线程同时用,也不必考虑线程安全问题。

       便于配合常量池的使用:常量池会把一些相同的字符重复使用,避免每次都创建相同的对象,节省空间。所以就可能存在两个相同内容的String类指向常量池的同一字符串。当其中一个String变量改变时会创建新的空间来存储,不会对原来空间存放的字符串产生任何影响。因此就保证了另一个String变量的内容不会受影响。当没有String变量指向该空间时该空间会被java JVM自动回收,不会造成内存浪费。

4ae203d59bcc86ad9226fad135c474fb.png

       避免了许多网络安全问题:网络上数据库的用户名、密码等都是以String的形式传入来连接相应的数据库,如果String是可变的那么就容易被其他人钻空子修改你输入的String的值造成安全隐患。而且我们输入的用户名,密码等都是不需要改变的因此String为不可变类既可以保证安全又不影响用户使用。

        提高运行速度:String在创建的时候被hashcode给缓存了,不需要重新计算。因此在String的处理速度上往往比其他可变类要快。例如同样是要输出一个字符串的长度,该字符串被可变类存储时需要先计算才可以输出该字符串的长度。而被String存储时不需要计算,直接有变量存储字符串的长度,直接输出即可。这样就大大节约了程序运行的时间。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值