论坛首页 入门技术论坛

精辟的String与StringBuffer(StringBuilder)的区别

浏览 52150 次
精华帖 (4) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-21  

今天有空,下了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的操作都是改变赋值地址而不是改变值操作

   发表时间:2007-11-30  
没看懂
public static void stringReplace (String text) {   
   text = text.replace('j' , 'i');    
}——这个方法根本不起作用因为text只是引用拷贝。
似乎是在讲参数传递问题?和可变不可变对象有啥关系?
0 请登录后投票
   发表时间:2007-11-30  
SINCE1978 写道
没看懂
public static void stringReplace (String text) {   
   text = text.replace('j' , 'i');    
}——这个方法根本不起作用因为text只是引用拷贝。
似乎是在讲参数传递问题?和可变不可变对象有啥关系?


不是引用拷贝,两个对象指向同一段内存
0 请登录后投票
   发表时间: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 了么?
}
1 请登录后投票
   发表时间:2007-11-30  
   String 是不可以变的字符串.
   StringBuffer 是可变的字符串.
对StringBuffer进行操作,是在原来的对象之上进行改变. 而对String进行操作,是创建新的对象. 
1 请登录后投票
   发表时间:2007-12-03  
3:String 与StringBuffer的区别

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

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

以把字符串设为共享的。

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

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

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

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

用StringBuffer类就避免了这个问题.
3 请登录后投票
   发表时间:2008-07-30  
janmy 写道
3:String 与StringBuffer的区别

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

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

以把字符串设为共享的。

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

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

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

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

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

这个老兄回答的正确啊
1 请登录后投票
   发表时间: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



0 请登录后投票
   发表时间: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。
0 请登录后投票
   发表时间:2008-10-28  
public class Test {
    public static void stringReplace(String text) {
        //把textString的地址copy给text,text也指向了textString的"java"
        //text.replace('j', 'i');的结果是"iava"
        //text = text.replace('j', 'i');就是重新使text指向"iava"
        //由于该方法的返回类型是void,所以原来的textString没变
        text = text.replace('j', 'i');
    }

    public static void bufferReplace(StringBuffer text) {
        //textBuffer的地址copy给text
        //然后沿着text指向的字符串(其实也就是textBuffer指向的对象)操作,添加一个"C"
        //虽然没有任何返回,但是这个操作影响到了textBuffer所指向的字符串
        //所以上个方法打印"java",这个方法打印"javaC"
        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);
    }
}
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics