`
yiliner
  • 浏览: 215009 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

对 String 跟 StringBuffer 的理解

阅读更多

    在计算机程序设计中,字符串操作应该是最常见的行为之一,在 Web 系统的开发中更是如此。我觉得在Java中最应用最广泛的对字符串操作算是 String 类跟 StringBuffer 类了。

    那么,到底 String 跟 StringBuffer 有什么区别跟联系呢?

    首页,String 对象是不可变的。当我们修改一个 String 对象的值的时候,实际上都是重新创建了一个 String 对象,用以包含修改了以后的 String 类容。而最初的 String 对象则丝毫未动。

Java代码 复制代码
  1. public class TestString {   
  2.     public static void main(String[] args) {   
  3.         String s = "";   
  4.         s = "String";   
  5.         System.out.println("The string is : " + s);   
  6.     }   
  7. }  
public class TestString {
	public static void main(String[] args) {
		String s = "";
		s = "String";
		System.out.println("The string is : " + s);
	}
}

    在上例中,首先创建了一个 String 对象 s,初始值为 "" ,然后再给它赋值 "String",但是在内存中并不是简单的改变一下 s 引用指向的对象在内存中的数据池的值改变为 "String" 哦,实际上是在堆内存中重新开辟一个新的字符串空间,并赋值为 "String",然后复制一份原来 String 对象的引用,并指向这个新的字符串。

    上面这段代码是对字符串的操作,看上去好像是没有问题的,但是需要说明的是这段代码的运行效率十分低下。我们可以通过 javap -c TestString 命令反编译这段代码,得到如下代码:

Java代码 复制代码
  1. Compiled from "TestString.java"  
  2. public class TestString extends java.lang.Object{   
  3. public TestString();   
  4.   Code:   
  5.    0:   aload_0   
  6.    1:   invokespecial   #1//Method java/lang/Object."<init>":()V   
  7.    4:   return  
  8.   
  9. public static void main(java.lang.String[]);   
  10.   Code:   
  11.    0:   ldc     #2//String   
  12.    2:   astore_1   
  13.    3:   ldc     #3//String String   
  14.    5:   astore_1   
  15.    6:   getstatic       #4//Field java/lang/System.out:Ljava/io/PrintStream;   
  16.    9:   new     #5//class java/lang/StringBuilder   
  17.    12:  dup   
  18.    13:  invokespecial   #6//Method java/lang/StringBuilder."<init>":()V   
  19.    16:  ldc     #7//String The string is :   
  20.    18:  invokevirtual   #8//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   
  21.    21:  aload_1   
  22.    22:  invokevirtual   #8//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   
  23.    25:  invokevirtual   #9//Method java/lang/StringBuilder.toString:()Ljava/lang/String;   
  24.    28:  invokevirtual   #10//Method java/io/PrintStream.println:(Ljava/lang/String;)V   
  25.    31:  return  
  26.   
  27. }  
Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String
   2:   astore_1
   3:   ldc     #3; //String String
   5:   astore_1
   6:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   9:   new     #5; //class java/lang/StringBuilder
   12:  dup
   13:  invokespecial   #6; //Method java/lang/StringBuilder."<init>":()V
   16:  ldc     #7; //String The string is :
   18:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   21:  aload_1
   22:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   25:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   28:  invokevirtual   #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   31:  return

}

     一段简单的代码,短短三条语句怎么变化了这么多呢?原因就在于 String 是不可变的!Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。而这个重载的处理可能因此误导很多人对 Java 中 String 的使用。

    在上面的代码中可以发现 其实字符串串联是通过 StringBuilder (或 StringBuffer )类及其 append 方法实现的。JDK 帮助文档 写道:

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder (or StringBuffer ) class and its append method. String conversions are implemented through the method toString , defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification .  
Thinking In Java 写道
    String 对象是不可变的,你可以给一个 String 对象加任意多的别名,因为 String 对象具有只读特性,所以指向它的任何引用都不可能改变它的值,因此,也就不会对其他的引用有什么影响。

    而 StringBuffer 是一个线程安全的可变字符序列。最主要的就是“可变”这两个字。这就意味着对 StringBuffer 的操作可以提升程序执行的效率。

JDK 帮助文档 写道
Every string buffer has a capacity. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger. As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

    StringBuffer 跟 StringBuilder 相比,都可以支持字符串的操作,但是在单线程中建议还是用 StringBuilder,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。 不过 StringBuilder 在多线程中是不安全的,所以在多线程的应用中最好还是用 StringBuffer。

    如果你是要对字符串经常性的进行操作,StringBuffer 绝对比 String 要好,最后只需要调用 StringBuffer 的 toString 方法,就可以以一个最终的 String 形式保存了。

    以上只是我对这两个类的一点点理解,希望各位有补充的尽量提出来,不胜感激。.....

分享到:
评论

相关推荐

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`...理解`String`、`StringBuffer`和`StringBuilder`的区别和使用场合,可以帮助开发者写出更高效、更安全的代码。在实际开发中,应根据项目需求和环境选择合适的字符串处理类。

    String、StringBuffer与StringBuilder之间区别

     StringBuffer:字符创变量  StringBuilder:字符创变量  从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:

    String-StringBuffer-StringBuilder

    总的来说,`String`、`StringBuffer`和`StringBuilder`各有其适用的场合,理解它们之间的差异和特性,能够帮助开发者编写出更加高效、安全的代码。在实际开发中,应根据需求和上下文灵活选择合适的字符串处理类。

    String与StringBuffer区别详解

    每次对`String`对象进行修改(如连接、替换字符等),都会生成一个新的`String`对象。这是因为`String`对象存在于常量池中,修改操作实际上是在常量池中创建新的引用,而不是修改原有的对象。 - `StringBuffer`(或...

    string与stringbuffer的区别

    字符串在Java中的表现形式主要有两种:`String`和`StringBuffer`(或者`StringBuilder`)。它们之间的主要区别在于可变性、性能和使用场景。 1. **不可变性**: `String`类是不可变的,这意味着一旦创建了一个`...

    String、StringBuilder和StringBuffer的区别

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...

    java面试笔试题String 和StringBuffer的区别

    在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...

    JAVA中String与StringBuffer的区别 自己的学习笔记总结

    ### JAVA中String与StringBuffer的区别 在Java编程语言中,`String` 和 `StringBuffer` 都是非常重要的类,它们用于处理字符串数据。虽然它们都实现了字符串操作的功能,但它们之间存在一些重要的区别,这些区别...

    String和StringBuffer详细用法总结

    根据给定的信息,本文将对`String`与`StringBuffer`在Java中的使用进行详细的解析...通过以上的分析与讨论,我们可以更好地理解和掌握`String`与`StringBuffer`在实际开发中的应用技巧,从而写出更高效、更可靠的代码。

    String&Stringbuffer

    相比于`String`,`StringBuffer`支持对其内部字符序列进行添加、删除或替换等操作,且这些操作不会产生新的对象,而是直接在原对象上进行修改。由于`StringBuffer`的线程安全特性,它非常适合多线程环境下的字符串...

    String和StringBuffer 的区别 .txt

    下面通过具体的代码示例来进一步理解`String`和`StringBuffer`之间的差异: ```java public class Untitled1 { public static void main(String[] args) { String s1 = "STRING值不变-&gt;"; String s2 = s1; ...

    Java String 与 StringBuffer 用法区别

    在Java中,字符串是常量,每次对`String`对象进行修改操作,如拼接,实际上都会创建一个新的`String`对象。这是由于Java为了保证线程安全和数据一致性,确保字符串的不变性。例如,以下代码: ```java String str =...

    String&StringBuffer&StringBuilder三者之间的区别-经典解析.doc

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自有特定的使用场景和特性。理解这三个类的区别对于任何Java开发者,无论是初学者还是经验丰富的程序员,都是非常重要的...

    初步支持String和StringBuffer类

    在Java编程语言中,`String`和`StringBuffer`类是处理字符串的两个核心类,它们在日常开发中扮演着重要角色。这篇文章将深入探讨这两个类的特性、用途以及它们之间的区别。 首先,`String`类是不可变的,这意味着...

    5讲String、StringBuffer、Stri...1

    Java中的字符串处理是编程中常见的任务,涉及到三个主要的类:String、StringBuffer和StringBuilder。它们之间的主要区别在于线程安全、性能和可变性。 首先,`String`类是不可变的,这意味着一旦创建了一个`String...

    面试的经典程序(String,StringBuffer,list,Connections)

    熟练运用`String`、`StringBuffer`进行字符串操作,理解数组和集合容器的数据结构及其应用场景,以及如何在多线程环境中正确处理数据库`Connection`,都将有助于你在面试中脱颖而出。通过深入学习和实践,你可以...

    java CharSequence、String、StringBuffer、StringBuilder详解

    通过分析提供的`String.java`、`StringBuffer.java`和`StringBuilder.java`源码,我们可以深入理解这些类的内部实现,例如它们如何处理字符序列,以及在进行字符串操作时的内存分配和性能优化策略。源码阅读有助于...

Global site tag (gtag.js) - Google Analytics