字符串的特性

一、字符串常量的特性

下面的代码创建了几个对象?

很明显,创建了三个对象。只要是用new 创建的对象,都是一个 新对象。那s3,s4怎么是一个对象呢?这和字符串常量的特性有关。

字符串常量存储在字符串暂存池中,以键值对的形式存储,键中存储字符串的内容,值中存储字符串的地址。当我们使用某个字符串常量的时候,首先会去暂存池中查找这个字符串是否存在,如果存在,直接返回键值对中的value.字符串常量的这个特性依赖于字符串的不可变性实现。

再看另一个例子 :

上面的代码只创建了一个对象。为何s5和前面的是一个对象?

再变化一下:

很明显创建了5个对象。对于string s2=a+b+c;这句代码,因为a,b,c是变量 ,在这之前可能重新赋值,所以相加后是个新的对象,而string s5="a"+"b"+"c";是三个固定的值相加,所以合并后和s4是同一个变量。这个结论只适合字符串常量。

二、字符串的不可变性

1 #region 字符串的不可变性
2             string s1 = "abc";
3             s1 = "cba";
4             Console.WriteLine(s1);
5             #endregion
View Code

上面的代码中,先是在内存中开辟了一块内存,存储abc,然后让s1指向这块内存,然后又开辟了块内存,存储cba,让s1指向新开辟的内存。开辟的两块内存在程序退出前是一直存在的,只是我们只输出了新开辟的内存中的内容。当给一个变量新赋值一个字符串的时候,原来的内存中的字符串的内容不会改变,这就是字符串的不可变性。

下面的代码在内存中开辟了多少块内存?

1 string s = "a";
2             s = s + "b";
3             s = s + "c";
4             s = s + "d";
5             Console.WriteLine(s);
View Code

7块。因为不是对字符串常量进行操作,所以每次给s加上一个字符串的时候,出了新开辟的b,c,d所占的内存外,还会给拼接的字符串开辟内存。由此,可见,用这种方式拼接字符串是相当耗资源的。

tips:

1.声明字符串开辟的内存,只有当程序退出后,才会释放,所以不要把大文本字符串用变量保存起来。可以先把大文本保存到一个txt文件中,用对应的方法读取,方法执行完成后,就释放了资源,能提高程序的性能。

2.拼接字符串可用stringbuilder对象。

下面的代码可以看出string 和stringbuilder的性能的差距;

 1  //string s = string.Empty;
 2             StringBuilder s = new StringBuilder();
 3             Stopwatch stop = new Stopwatch();
 4             stop.Start();
 5             for (int i = 0; i < 200000; i++)
 6             {
 7                 //s += "a";////00:00:14.3903122
 8                 s.Append("a");//00:00:00.0025962
 9             }
10             stop.Stop();
11             Console.WriteLine(stop.Elapsed);
12             Console.WriteLine("ok");
View Code
原文地址:https://www.cnblogs.com/wesley168/p/6491448.html