`
大鹏展翅XS
  • 浏览: 2936 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA中String、Stringbuffer和StringBuilder的区别

阅读更多
<div class="iteye-blog-content-contain" style="font-size: 14px"></div>
String、Stringbuffer和StringBuilder的区别:
·String对象的内容不允许修改;
·StringBuffer对象的内容可以修改,所有的方法都使用了synchronized声明,属于线程安全的操作(查看JDK的源码即可看到);
·StringBuilder是JDK1.5之后追加的新类,此类对象可以修改,所有方法使用异步处理,属于非线程安全的操作。
总结来讲,开发的首选还是String类,要修改数据,需要保证线程安全,使用StringBuffer;如果不需要保证线程安全,则使用StringBuilder。其实StringBuffer和StringBuilder在性能上的差距并不是很大,如何选择主要看个人编码习惯。
下面详细介绍String和StringBuffer(StringBuilder应用很少):
一.String类详解
1、String类既然是类,那么它实例化的时候就必须依靠对象,而String类的对象有两种定义方式:
·直接赋值:String str = “Hello”;
·利用构造方法完成,String是一个类,那么既然是类就一定会提供有构造方法,那么在String类里面提供有一个有参构造:public String(String str);
从使用上来讲第一种更简单,但是第二种更符合程序员的习惯性思维。
那么两种实例化方式有什么区别?
|-直接赋值:String str = “hello”;
字符串常量是String类的匿名对象(因为字符串常量可以调用String类的方法,如”hello”.equals(str)),直接赋值的内存关系如下图所示:




此时通过内存关系图可以发现,只开辟了一块堆内存空间。
|-采用构造方法进行处理
String str = new String(“hello”);
此种实例化方式的内存关系如下图所示:




通过观察内存图可以发现,此种方式实例化String类对象时产生了两块堆内存空间,并且有一块是垃圾空间,正是因为如此,我们不会采用此类模式。
此时String类两种实例化方式的区别便可总结如下:
*直接赋值:只会开辟一块堆内存空间;
*构造方法实例化:会开辟两块堆内存空间,并且有一块将成为垃圾。
考虑到以上区别, 在开发之中全部要求使用直接赋值的模式完成

2.字符串一旦声明则不可改变
  字符串的内容是不可变的,但是在实际应用过程中,我们用“+”实现了字符串的连接,这个不就是改变了字符串的内容吗?
假设有如下代码:
public class TestString {
public static void main(String args[]) {
String str = "hello " ;
str = str + "world " ;
str += "!!!" ;
System.out.println(str) ;
}
}
该程序的执行内存图如下所示:





通过以上的分析可以发现,所谓的字符串的内容的修改本质上也只是对象引用的变化而已。那么正因为如此,所以在以后的开发之中此类代码必须要回避,不能使用的过多。因为如果是高并发的访问的话,内存一定会被沾满,因为垃圾回收还没执行前可能内存空间就已经被沾满了。

3.字符串的比较以及对象池的概念
要表较两个int型的数据是否相等,可以用“==”进行比较。如果要比较两个字符串,是不是也可以使用“==”呢?请看下面代码:
public class TestString {
public static void main(String args[]) {
String strA = "hello" ; //直接赋值
String strB = new String("hello") ; //使用构造方法实例化
String strC = strB ; //
System.out.println(strA == strB) ; // false
System.out.println(strA == strC) ; // false
System.out.println(strB == strC) ; // true
}
}
为什么会出现上面的结果呢?请看下面的内存关系图。







通过以上的分析可以看出,使用“==”的确可以比较String类对象是否相等,但是它比较的只是两个对象的内存地址数值,并没有比较字符串的内容,所以结果为false。若需要比较字符串的内容,可以利用String类中定义的对象比较的方法:
public boolean equals(Object anObject);  如strA.equals(strB);
另有一点需要注意一下,在使用equals()方法进行比较,最好用肯定不会为null的变量来调用equals()方法,否则很容易出现NullPointerException的异常。如下面代码所示:
public class TestString {
public static void main(String args[]) {
String userName = null ; //
if ( “hello”.equals(userName)) {
System.out.println("两个对象内容相同。") ;
} else {
System.out.println("两个对象内容不相同。") ;
}
}
}
下面再来解释下对象池的概念:
public class TestString {
public static void main(String args[]) {
String strA = "hello" ;
String strB = "hello" ;
String strC = "hello" ;
System.out.println(strA == strB) ; // true
System.out.println(strB == strC) ; // true
System.out.println(strA == strC) ; // true
}
}
以上三个String类的对象,内容都是相同,并且通过代码的执行结果可以发现, “==”比较的是两个对象的地址数值,那么如果是相同的,就说明这三个对象都指向想了同一个堆内存(因为通过以上分析可知,“==”比较的是堆内存的地址编码)。内存示意图如下所示:





实际上在JVM的底层有一块内存区域(对象池),对象池是一块共享的数据区,所有的其他对象都可以共享这一个对象池中的内容。String类的设计正好使用了这种共享设计模式的概念。
如果采用直接赋值的方式定义有一个String类对象,那么此对象一旦声明之后将保存在对象池之中。以供下次继续使用。而当继续采用直接赋值的方式再次声明一个字符串时,这时会首先在对象池中进行查找,看对象池中是否有该字符串,如果发现有该内容,则不会开辟新的堆内存空间,而将已有字符串的堆内存的指向交由新的String类对象。如果对象池中不存在该字符串,则开辟新的堆内存空间,并将该字符串自动入池。
补充:用构造方法实例化的字符串对象不能实现自动入池,但是可以通过String类中public String intern();如String str = new String(“hello“); str.intern()即可实现字符串手动入池。
解释String类两种实例化方式的区别?
·直接赋值:只会开辟一块堆内存空间,并且声明的对象可以自动保存在对象池之中,以供相同内容的字符串对象引用;
·构造方法实例化:会开辟两块堆内存空间,并且有一块堆内存将成为垃圾,此类模式产生的实例化对象,不会自动入池,但是可以通过intern()方法实现手工入池。
二、StringBuffer类详解
  StringBuffer本身也属于一个字符串的操作类,但是很明显里面带有一个Buffer就表示缓冲。所以一旦带有缓冲的操作,那么一般有两个意义:一个意义是可以快速的修改,另一个意义是可以快速的读取。
  String类对象的内容不可改变,而StringBuffer类对象的内容可以改变。
1.实例化方式的比较:
·String类有直接赋值实例化和采用构造方法实例化两种实例化方式;
·StringBuffer类只能通过构造方法进行实例化;StringBuffer but = new StringBuffer();
2.字符串连接方式的比较:
·String类中用“+”完成字符串之间的连接;如str1 = “hello”; str2 = “world”; str = str1 + str2;
·StringBuffer类中要实现字符串之间的连接,需要使用append();
  public String append(StringBuffer buf);如buf1 = “hello”;buf2 = “world”;
buf = buf1.append(buf2);
3.String和StringBuffer之间的转换
  查看javaSE的API文档可以发现,String和StringBuffer都是CharSequence接口的子类,但是这两个类的对象绝对不可能直接转换。
|-String变为StringBuffer:
·直接利用StringBuffer类提供的构造方法:public StringBuffer(String str);
StringBuffer buf = new StringBuffer(“hello”);
·直接利用append()方法将字符串保存在StringBuffer之中:
StringBuffer buf = new StringBuffer();
Buf.append(“hello”);
|-StringBuffer变为String
任何类的对象都可以变为String类型,因为所有类中都提供有toString()方法:
StringBuffer buf = new StringBuffer();
buf.append(“hello”);
String str = buf.toString();
总结:在开发中由于StringBuffer可以被改变,所以很少用其作为引用传递或返回数据类型。作为参数或返回类型的时候90%的情况下都会选择String。

  • 大小: 66.1 KB
  • 大小: 70.6 KB
  • 大小: 79.9 KB
  • 大小: 47.1 KB
  • 大小: 66.2 KB
  • 大小: 57.2 KB
分享到:
评论

相关推荐

    String StringBuffer和StringBuilder区别之源码解析

    "String StringBuffer和StringBuilder区别之源码解析" 在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、...

    String、StringBuffer与StringBuilder之间区别

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

    String及StringBuffer和StringBuilder的区别

    String、StringBuffer 和 StringBuilder 是 Java 语言中三种不同类型的字符串处理方式,它们之间存在着明显的性能和线程安全性差异。 String String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一...

    Java中String,StringBuffer与StringBuilder的区别

    最后,让我们总结一下 Java 中 String, StringBuffer 与 StringBuilder 三种字符串类型的区别和用法。String 类型是不可变的对象,性能不好,适合不需要修改的字符串对象。StringBuffer 类型是可变的对象,性能好,...

    String ,StringBuffer与StringBuilder

    在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String 对象,就不能修改它的值。每次对 String 对象的...

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...

    String、StringBuilder和StringBuffer的区别

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

    Java 中 String,StringBuffer 和 StringBuilder 的区别及用法

    "Java 中 String、StringBuffer 和 StringBuilder 的区别及用法" Java 中 String、StringBuffer 和 StringBuilder 是三个常用的字符串操作类,了解它们之间的区别对 Java 开发者来说非常重要。本文将详细介绍这三者...

    String-StringBuffer-StringBuilder

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...

    《剑指offer》Java-String、StringBuffer 和 StringBuilder 的区别.pdf

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的对象,但它们之间存在显著的区别。String是最常见的字符串类型,它的特点是不可变性。这意味着一旦一个String对象被创建,就不能进行...

    浅谈java中String StringBuffer StringBuilder的区别

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的类,但它们之间存在显著的性能和功能差异。下面我们将深入探讨这三个类的区别。 首先,`String`类是Java中最基本的字符串类型,它表示...

    你知道String、StringBuffer和StringBuilder的区别吗

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自具有不同的特性和使用场景。下面将详细解析这三个类的区别。 首先,`String`类是最基础的字符串处理类,它被设计为不...

    Java中String、StringBuffer、StringBuilder的区别详解

    Java中的字符串处理是编程中常见的任务,涉及到三个关键类:String、StringBuffer和StringBuilder。它们在功能上相似,但有着重要的区别,主要体现在字符串的可变性、线程安全性和性能方面。 1. 可变性 - String类...

    java 中String和StringBuffer与StringBuilder的区别及使用方法

    Java 中 String 和 StringBuffer 与 StringBuilder 的区别及使用方法 Java 中 String、StringBuffer 和 StringBuilder 是三个常用的字符串操作类,每个类都有其特点和使用场景。在开发过程中,正确选择合适的字符串...

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

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

    string,stringBuffer,stringBuilder

    string,stringBuffer,stringBuilder

    StringBuffer 和 StringBuilder 类

    在Java编程中,当我们需要对字符串进行多次修改时,StringBuffer和StringBuilder类成为首选。这两个类提供了一种高效且灵活的方式来处理字符串,与不可变的String类相比,它们能避免创建大量未使用的对象,从而提高...

    Java面试题-每日一题:String、StringBuffer、StringBuilder的区别

    Java面试题-每日一题:String、StringBuffer、StringBuilder的区别

    Java中StringBuffer和StringBuilder_动力节点Java学院整理

    在Java编程语言中,`StringBuffer`和`StringBuilder`类都是用来处理字符串的,它们的主要功能是构建和操作字符串。这两个类与`String`类不同,`String`类是不可变的,这意味着一旦创建了一个`String`对象,就不能...

Global site tag (gtag.js) - Google Analytics