今天有空,下了scjp的题目做做,想起了一个本来想写却又没写的问题。这个问题几乎已成为面试必问题,虽然答案很简单,但回答出确又真正理解的人我觉得并不多。

String与StringBuffer的区别?

如果你在网上一搜,会有非常多的答案,其中最多的就是String是不可变而StringBuffer是可变的,但是这可变与不可变究竟是什么意思呢?如果你能用IDE进行debug的话,你就会发现,String实例化以后所有的属性都是final的,而StringBuffer确不是,这就是可变与不可变。下面引用SCJP的试题来解释一下这个例子:

java 代码
  1. public class Test {   
  2.    public static void stringReplace (String text) {   
  3.    text = text.replace('j' , 'i');    
  4.    }   
  5.       
  6.    public static void bufferReplace (StringBuffer text) {   
  7.    text = text.append("C");    
  8.    }   
  9.       
  10.     public static void main (String args[]) {    
  11.     String textString = new String ("java");    
  12.     StringBuffer textBuffer = new StringBuffer ("java");    
  13.        
  14.     stringReplace (textString);    
  15.     bufferReplace (textBuffer);    
  16.        
  17.     System.out.println (textString + textBuffer);    
  18.     }    
  19.     }   

答案是 javajavaC

这是因为第七行text = text.append ("C"),append方法会改变text中的值,而text与textBuffer指向的地址是相同的。因此会打印javaC

再举个例子:

String a = "a";  //假设a指向地址0x0001

a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的。

因此String的操作都是改变赋值地址而不是改变值操作

评论
n5281407 2008-08-12
wangsong76 写道
       
public class testStringStringBuffer {
   public static void stringReplace (String text) {    
   text = text.replace('j' , 'i');  
   System.out.println (text); 
   }    
       
   public static void bufferReplace (StringBuffer text) {    
   text = text.append("C");     
   }    
       
    public static void main (String args[]) {     
    String textString = new String ("java");     
    StringBuffer textBuffer = new StringBuffer ("java");     
        
    stringReplace (textString);     
    bufferReplace (textBuffer);     
        
    System.out.println (textString + textBuffer);     
    }     

}


输出:
iava
javajavaC






假设调用stringReplace方法的参数text的内存地址是0x0001的话,在执行 text = text.replace('j' , 'i'); 以后,text的内存地址就会变成类似0x0002的地址,但是肯定不再是0x0001了,原因就是String类是final的,任何修改都将创造一个新的字符串。那么在stringReplace方法里面输出text,就应该是0x0002地址里的内容了,iava。
wangsong76 2008-08-05
       
public class testStringStringBuffer {
   public static void stringReplace (String text) {    
   text = text.replace('j' , 'i');  
   System.out.println (text); 
   }    
       
   public static void bufferReplace (StringBuffer text) {    
   text = text.append("C");     
   }    
       
    public static void main (String args[]) {     
    String textString = new String ("java");     
    StringBuffer textBuffer = new StringBuffer ("java");     
        
    stringReplace (textString);     
    bufferReplace (textBuffer);     
        
    System.out.println (textString + textBuffer);     
    }     

}


输出:
iava
javajavaC
virusswb 2008-07-30
janmy 写道
3:String 与StringBuffer的区别

String:在String类中没有用来改变已有字符串中的某个字符的方法,由于不能改变一个java字符串中的某个单独

字符,所以在JDK文档中称String类的对象是不可改变的。然而,不可改变的字符串具有一个很大的优点:编译器可

以把字符串设为共享的。

StringBuffer:StringBuffer类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。这样使用

StringBuffer类的append方法追加字符 比 String使用 + 操作符添加字符 到 一个已经存在的字符串后面有效率得

多。因为使用 + 操作符每一次将字符添加到一个字符串中去时,字符串对象都需要寻找一个新的内存空间来容纳更大

的字符串,这无凝是一个非常消耗时间的操作。添加多个字符也就意味着要一次又一次的对字符串重新分配内存。使

用StringBuffer类就避免了这个问题.

这个老兄回答的正确啊
janmy 2007-12-03
3:String 与StringBuffer的区别

String:在String类中没有用来改变已有字符串中的某个字符的方法,由于不能改变一个java字符串中的某个单独

字符,所以在JDK文档中称String类的对象是不可改变的。然而,不可改变的字符串具有一个很大的优点:编译器可

以把字符串设为共享的。

StringBuffer:StringBuffer类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。这样使用

StringBuffer类的append方法追加字符 比 String使用 + 操作符添加字符 到 一个已经存在的字符串后面有效率得

多。因为使用 + 操作符每一次将字符添加到一个字符串中去时,字符串对象都需要寻找一个新的内存空间来容纳更大

的字符串,这无凝是一个非常消耗时间的操作。添加多个字符也就意味着要一次又一次的对字符串重新分配内存。使

用StringBuffer类就避免了这个问题.
myworkfirst 2007-11-30
String 是不可以变的字符串.
StringBuffer 是可变的字符串.
对StringBuffer进行操作,是在原来的对象之上进行改变. 而对String进行操作,是创建新的对象.
抛出异常的爱 2007-11-30
foy 写道
SINCE1978 写道
没看懂
public static void stringReplace (String text) {
text = text.replace('j' , 'i');
}——这个方法根本不起作用因为text只是引用拷贝。
似乎是在讲参数传递问题?和可变不可变对象有啥关系?


不是引用拷贝,两个对象指向同一段内存


string是不可变的。。。
比如这个:
test(x000001).replace(“j”,"i");

内部分是这样的:
String reqlace("j","i"){
 //self="java";
 // .......dosomthing
 return new String ("iava");//看到这个new 了么?
}
foy 2007-11-30
SINCE1978 写道
没看懂
public static void stringReplace (String text) {
text = text.replace('j' , 'i');
}——这个方法根本不起作用因为text只是引用拷贝。
似乎是在讲参数传递问题?和可变不可变对象有啥关系?


不是引用拷贝,两个对象指向同一段内存
SINCE1978 2007-11-30
没看懂
public static void stringReplace (String text) {
text = text.replace('j' , 'i');
}——这个方法根本不起作用因为text只是引用拷贝。
似乎是在讲参数传递问题?和可变不可变对象有啥关系?
发表评论

提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则

您还没有登录,请登录后发表评论

jessdy
  • 浏览: 9188 次
  • 性别: Icon_minigender_1
  • 来自: 上海虹口区
  • 详细资料
搜索本博客
最近加入圈子
存档
最新评论