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();

测试上述代码两者的性能相差数百倍。


posted @ 2011-09-24 23:30  一斤半  阅读(649)  评论(0编辑  收藏  举报