博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈string的不可改变性质和“+”拼接字符串
阅读量:3898 次
发布时间:2019-05-23

本文共 958 字,大约阅读时间需要 3 分钟。

我们都知道String对象一旦创建就不可改变,那这是为什么呢?

那我们就从源代码入手,去分析String是如何维护其不可改变的性质。

手段一:final类和final的私有成员

在这里插入图片描述
可以发现:
String是一个final类,且三个成员都是私有的,这就意味着String是不可被继承的,这样就可以防止出现程序猿通过继承重写String类的方法使得String类是“可变的”的情况。
每个String对象维护着一个char数组–>私有成员value。它是String的底层数组,用于存贮字符串的内容,而且是private final,但是数组是引用类型,所以只能限制引用不能改变而已。也就是说数组元素的值是可以改变的。

我们来做一个小实验:

在这里插入图片描述
可以看到:字符串str使用数组arr来构造一个对象,当数组arr修改其元素值后,字符串str并没有跟着改变。

然后我们再看一下它的构造方法是怎么样的。

在这里插入图片描述
可以看出:String在使用外部char数组构造对象的时候,是重新复制了一份外部char数组,从而不会让外部数组的改变影响到String对象

手段二:改变即创建对象的方法

在这里插入图片描述

我们都是知道String有很多方法,这里以substring()为例,
可以看出,如果不是切割整个字符串的话,就会新建一个对象,也就是说,只要与原字符串不相等,就会新建一个String对象。这也就是在大量修改字符串的时候不建议使用String的原因,白白浪费内存。

既然说到string,就不得不说一说string的拼接字符串 “+”

先来看一个程序,看看不同情况下的输出:

在这里插入图片描述
在这里插入图片描述
s2的结果其实在编译期间就已经计算出来了(常量表达式的计算就是在编译期间完成的),与s1的值是一样的,所以在类加载时创建并维护在常量池中。但是s3的表达式含有变量s2,只能是运行时才能执行计算,也就是说在运行时才计算出他的结果,并且底层是new了一个StringBuilder对象,调用append()方法来实现拼接,所以它在堆中创建对象,s4就更不用讲了,直接在堆中new一个对象。

内存里的情况:

在这里插入图片描述
从这里也就可以看出:当需要大量拼接字符串的时候,直接定义StringBuffer的对象,
直接调用append()方法去拼接就好了,不然就像s3一样会创建对象,这样也就浪费内存。

转载地址:http://gnyen.baihongyu.com/

你可能感兴趣的文章
【MacOS】Mac 系统下类似于 apt-get 的软件包管理器 -- Homebrew
查看>>
为窗口添加鼠标HOVER和LEAVE事件
查看>>
VC小技巧20个
查看>>
MFC Feature Pack for Visual C++ 2008的BUG之一
查看>>
POJ - 2739 Sum of Consecutive Prime Numbers
查看>>
STL map映照容器(一)map创建、元素插入、元素删除和遍历访问
查看>>
Leetcode - 557反转字符串中的单词III
查看>>
Leetcode - 160相交链表
查看>>
Leetcode - 11盛最多水的容器
查看>>
Leetcode - 141环形链表
查看>>
Leetcode - 14最长公共前缀
查看>>
Leetcode - 7整数反转
查看>>
PAT---B1022. D进制的A+B (20)
查看>>
PAT---B1037. 在霍格沃茨找零钱(20)
查看>>
PAT---A1019. General Palindromic Number (20)
查看>>
PAT---A1027. Colors in Mars (20)
查看>>
PAT---1058. A+B in Hogwarts (20)
查看>>
PAT---A1001. A+B Format (20)
查看>>
PAT---A1005. Spell It Right (20)
查看>>
PAT---A1035. Password (20)
查看>>