对 String 跟 StringBuffer 的理解

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

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

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

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 命令反编译这段代码,得到如下代码:

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 形式保存了。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值