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

java中String,new String,StringBuffer的思考

阅读更多

java.lang.String类对大家来说最熟悉不过了,我们写java程序很少能不用String的。本文讲述如何正确的使用String,内容主要涉及初始化、串联和比较等操作。
    首先我们必须清楚的一点是String类是final类型的,因此你不可以继承这个类、不能修改这个类。我们使用String的时候非常简单,通常都是 String s = "hello",但是Java API中同时提供了一个构造函数为String(String s),因此你也可以这样使用String s = new String("hello",对于后面这样初始化一个String的方式是不推荐的,因为new操作符意味着将会在heap上生成一个新的对象,如果这样的操作发生在一个循环中,那么代价是惨重的。比如
for(int i = 0;i<1000;i++)
{
    String s = new String("hello";
}
这将会创建1000个String类型的对象,由于String类是final的,因此这样的操作事实上是每次都生成了一个新的String对象的。如果你使用String s = "hello";那么就可以实现复用了。
   看这两条语句:
   String   password="ok"; 
   String   password=new   String("ok";  
   不同的是,第一条现在内存中创建了"ok"这个String,然后将reference赋给password,如果这个时候还有一条语句String pwd = "ok";那么JVM将不再创建"ok",而是直接将第一个"ok"的reference赋给pwd,也就是说,password和pwd是使用同一块内存,而如果加上String   pwd   =   new   String("ok";那JVM将在内存中再创建一块区域放上“ok”这个字符串。
    通常对String的比较有两种情况,一个是使用==,另一个是使用equals()方法,注意==是对对象的地址进行比较的,而String中的 equals()方法是覆盖了Object类的方法,并且实现为对String对象的内容的比较。所以String s1 = new String("hello";String s2 = new String("hello",我们对s1和s2进行上述比较的时候,前者应该返回false,因为使用new生成的是两个不同的对象。后者应该返回 true因为他们的内容是一样的,都是"hello"。那么如果我们还有一个String s3 = "hello";他和s1的比较应该是什么样子的呢,答案是s1==s3为false,equals的比较位true。事实上String类是维持着一个 String池的,这个池初始化为空的,当我们String x = "hello"的时候,hello就会被放入这个池中,当我们再次String y = "hello"的时候,他首先去检查池中是否存在一个和hello内容一样的对象,如果存在的话就会把这个引用返回给y,如果不存在的话,就会创建一个并放入到池中。这样就实现了复用。在String有一个方法intern()他可以把String的对象放入到池冲并返回池中的对象。如果我们对s1 (String s1 = new String("hello")调用intern,s1 = s1.intern()这时候,我们再把s1和s3进行“==”的判断,你会发现结果返回true!

   String是一个final Class,StringBuffer不是。所以对于 String a = "yacht" ,String b = "yacht1" String c = a + b ; 存在一个对象拷贝构造和解析的消耗问题;对于一个StringBuffer来说,StringBuffer sb = new StringBuffer();sb.append("yacht" ; sb.append("yacht1"; 因为StringBuffer是一个可以实例化的类,而且它的内建机制是维护了一个capacity大小的字符数组,所以它的append操作不存在对象的消耗问题,所以我觉得如果存在String连接这种事情,StringBuffer来做会好很多。
    但事情并不是这么简单,看下面代码
    String a = "yacht1" + "yacht2" + "yacht3" + "yacht4";
    StringBuffer sb = new StringBuffer();
    sb.append("yacht1";
    sb.append("yacht2";
    sb.append("yacht3";
    sb.append("yacht4";
    String a = sb.toString();
    如果按照我先前说的看法,第一个效率肯定比第二个低,但经过测试不是这样,为什么?这里,我们需要理解程序过程的两个时期,一个是编译时,一个是运行时,在编译时,编译器会对你的程序做出优化,所以第一个的String a会被优化成yacht1yacht2yacht3yacht4,而第二个的StringBuffer只会在运行时才处理。所以效率是不一样的。
    如果代码是这样的:
    String a ;
    for(int i = 0; i< 100000;i++)
      a += String.valueOf(i);
     StringBuffer sb = new StringBuffer();
    for(int i = 0; i< 100000;i++)
     sb.append(i) ;
    String a = sb.toString();
    如果是这种情况的话,第一个的效率就大大不如蓝色,区别在哪里,就在于运行时和编译时的优化问题上!

效率:String 与 StringBuffer

    情景1:
    (1) String result = "hello" + " world";
    (2) StringBuffer result = new String().append("hello".append(" world";

        (1) 的效率好于 (2),不要奇怪,这是因为JVM会做如下处理
        编译前   String result = "hello" + " world";
        编译后   String result = "hello world";

    情景2:
    (1) public String getString(String s1, String s2) {
            return s1 + s2;
        }
    (2) public String getString(String s1, String s2) {
            return new StringBuffer().append(s1).append(s2);
        }

        (1) 的效率与 (2) 一样,这是因为JVM会做如下处理
        编译前   return s1 + s2;
        编译后   return new StringBuffer().append(s1).append(s2);

    情景3:
    (1) String s = "s1";
              s += "s2";
              s += "s3";
    (2) StringBuffer s = new StringBuffer().append("s1".append("s2".append("s3";

        (2) 的效率好于(1),因为String是不可变对象,每次"+="操作都会造成构造新的String对象

    情景4:
    (1) StringBuffer s = new StringBuffer();
        for (int i = 0; i < 50000; i ++) {
            s.append("hello";
        }
    (2) StringBuffer s = new StringBuffer(250000);
        for (int i = 0; i < 50000; i ++) {
            s.append("hello";
        }  
        (2) 的效率好于 (1),因为StringBuffer内部实现是char数组,默认初始化长度为16,每当字符串长度大于char
        数组长度的时候,JVM会构造更大的新数组,并将原先的数组内容复制到新数组,(2)避免了复制数组的开销

 

分享到:
评论

相关推荐

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

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

    String、StringBuffer、StringBuilder的使用方法

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

    Java中的String、StringBuffer和Math类

    ### Java中的String、StringBuffer和Math类 #### String类详解 **String类**在Java中扮演着极其重要的角色,主要用于处理不可变的字符序列。它不仅功能强大而且使用广泛,几乎所有的Java应用程序都会涉及到字符串...

    StringBuffer和String_区别

    ### StringBuffer与String的区别详解 #### 一、概念与特性 **String** 是 Java 中一个不可变的类,代表了字符序列。一旦一个 String 对象被创建后,其内容就不能被改变。这使得 String 类非常适合用来表示常量或者...

    java中 String和StringBuffer的区别实例详解

    Java中String和StringBuffer的区别实例详解 Java中String和StringBuffer都是用来存储字符串的对象,但是它们之间有着很大的区别。下面我们来详细介绍Java中String和StringBuffer的区别实例详解。 首先,String是不...

    String ,StringBuffer与StringBuilder

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

    Java String 与 StringBuffer 用法区别

    在Java编程语言中,`String`和`StringBuffer`是用来处理文本字符串的两种不同类,它们各有特点并适用于不同的场景。理解它们之间的区别对于优化代码性能至关重要。 首先,`String`类代表的是不可变的字符串。这意味...

    string和StringBuffer的区别

    在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在使用场景和性能上有显著的区别。了解这些差异对于编写高效、优化的代码至关重要。 首先,`String`类是不可变的。这意味着...

    Java中String和StringBuffer的区别.doc

    在Java编程语言中,String和StringBuffer是两个重要的类,它们在处理文本数据时有着显著的区别。String类代表不可变的字符序列,一旦创建,其值就不能改变。这意味着每次对String对象进行修改(如拼接操作)都会创建...

    String和StringBuffer详细用法总结

    根据给定的信息,本文将对`String`与`StringBuffer`在Java中的使用进行详细的解析与对比,并结合实例深入分析二者的异同及其适用场景。 ### `String` 和 `StringBuffer` 的基本概念 #### `String` 在Java中,`...

    Java 中String StringBuilder 与 StringBuffer详解及用法实例

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的重要类,它们各有特点,适用于不同的场景。这里我们将深入探讨这三个类的区别、特性和使用策略。 首先,String类是不可变的,这意味着...

    Java语言中StringBuffer的用法

    在Java编程语言中,`StringBuffer`类是一个非常重要的工具,尤其在处理字符串连接操作时。相较于`String`类,`StringBuffer`提供了线程安全的动态字符串构建,避免了频繁创建新对象带来的性能开销。本文将深入探讨`...

    String与StringBuffer区别详解

    在Java编程语言中,`String`和`StringBuffer`(在Java 5之后被`StringBuilder`取代,但在多线程环境中仍然使用`StringBuffer`)是处理文本字符串的两个核心类,它们各自有着不同的特性和用途。理解它们的区别对于...

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

    * String replace(CharSequence oldString, CharSequence newString):返回一个新字符串,这个字符串用 newString 字符串代替原始字符串中所以的 oldString 字符串。 * boolean startsWith(String prefix):如果字符...

    Java中字符数组、String类、StringBuffer三者之间相互转换

    Java中字符数组、String类、StringBuffer三者之间相互转换 Java语言中,字符数组、String类、StringBuffer三者之间的相互转换是一个非常重要的知识点。在实际开发中,我们经常需要在这三者之间进行转换,以满足不同...

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

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

    String和StringBuilder、StringBuffer的区别1

    在Java编程语言中,`String`、`StringBuilder`和`StringBuffer`是处理字符串的三种主要类型,它们各自具有不同的特性和使用场景。下面将详细解释它们之间的主要区别。 首先,`String`类是最基本的字符串类型,它...

    java 中string 和srtingbuffer的区别

    Java中的`String`和`StringBuffer`类在处理字符串时有着显著的区别,这些差异主要体现在字符串的可变性、性能和内存管理上。下面将详细分析这两个类的特点和使用场景。 1. 可变性: - `String`类:在Java中,`...

    String&Stringbuffer

    ### String与StringBuffer知识点...综上所述,`String`和`StringBuffer`在Java编程中各有其适用场景。选择合适的字符串类型可以显著提高程序的效率和可维护性。理解它们之间的差异并根据实际需求合理选用是非常重要的。

Global site tag (gtag.js) - Google Analytics