String变量的内容是只读的
String变量的最大出人意料的地方可能就是:它的内容是只读的!
不明真相的读者可能会争辩:不对啊,我明明可以修改String变量的值!请看一下代码,难道有错吗?
1 String s1="a";
2 s1="abcd";
上述代码确实没有错,代码执行后,s1的值的确为"abcd"。
这里的关键是:s1的第二个值"abcd"不是在第一个值"a"的基础上"扩展"而来的,实际上"abcd"和"a"是两个完全独立的String对象!
让我详细介绍代码背后的秘密:
当第一句代码执行时,CLR会在托管堆上分配一块内存,创建一个字符串对象,将"a"保存到此内存区域中,然后将次对象的引用保存在变量s1中。
当第二句代码执行时,CLR会在托管堆中重新分配一块内存区域存放"abcd",然后修改s1的值,让它引用此新创建的字符串对象。
另外在使用String类型的时候我的建议有如下:
1>避免使用加法运算符连接不同类型的数据例如:
1 String str="100+100="+20;
2 Console.WriteLine(str);
这样对性能会有较大的影响。
2>在循环中使用StringBuilder代替String实现连接字符串
1 String str="";
2 for (int i=1;i<=1000;i++)
3 {
4 str +=i;//引发“装箱”操作
5 if(i<1000) str+="+";
6 }
上述代码将生成一个很大的字符串:1+2+...+10000。
这里将要对进行10 000次的装箱操作,19 999次新字符串内存分配操作
改为如下代码,程序性能会得到改善:
1 StringBuilder buffer=new StringBuilder(4096)//预先分配4k的内存空间
2 for(int i=1;1<=10000;i++)
3 {
4 buffer.Append(i);
5 if(i<10000)
6 buffer.Append('+");
7 }
8 String result=buffer.ToString();
测试上述代码两者的性能相差数百倍。