一个stringbuffer的小问题,我的邮箱是mariah_fan@hotmail.com,欢迎交流。
问题:在string对象中有个构造函数是直接接受stringbuffer的。程序如下:
public string (stringbuffer buffer) {
synchronized(buffer) {
buffer.setshared();
this.value = buffer.getvalue();
this.offset = 0;
this.count = buffer.length();
}
}
在stringbuffer中:
final char[] getvalue() { return value; }
很明显的,这个构造函数直接把stringbuffer的char[]数组返回给了string对象。也就是现在新生成的string和stringbuffer共用同一个char[]数组,但是下面的程序为什么会打印出以下结果呢:
stringbuffer sb = new stringbuffer("abc");
system.out.println("stringbuffer: " + sb.tostring());
string s = new string(sb);
system.out.println("string: " + s);
sb.append("123");
system.out.println("stringbuffer: " + sb);
system.out.println("string: " + s);
/////////////////////////////////////////////////////////////////////
stringbuffer: abc
string: abc
stringbuffer: abc123
string: abc
分析:这个问题的核心答案在 this.count = buffer.length() 这句话上。这句话的意思是string中的count的大小为这个char[]数组中实际含有的字符的个数,而不是这个数组的大小。所以在打印的时候对于上面的string对象,只会打印3个字符,而不是六个字符!!
新的问题:如果我从stringbuffer中删除了一个字符,那么string对象也应该受到影响了?但是为什么实际上这个string没有发生变化呢?问题的答案在buffer.setshared()上,这句话的含义就是告诉这个stringbuffer,有其它的string对象与它共享它的char[]数组。这个时候,当它进行delete,insert等操作的时候,它会新生成一个char[]数组,然后再进行操作。所以这个时候string和stringbuffer就不共享同一个数组了,string自然也就不会受到影响了。
为什么要用这么复杂的方法呢?答案是“节省内存资源”。可以想想,我们在程序中使用最频繁的对象都有哪些?答案肯定包含string。而我们知道,在拼装一个string的时候,使用stringbuffer效率最高。所以我们会先用stringbuffer动态的拼装好一个字符串,然后再把它转化成string对象,这个时候就会突显这种方式的经典之处了。下面是stringbuffer的tostring()方法:
public string tostring() {
return new string(this);
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器