str = str + word;//字符串连接
与 tempStringBuffer.append(word);
有什么差别??
(str为Sring对象,tempStringBuffer为StringBuffer对象,word字符串字面量)在连接后  str 与 word所在 存储空间是不是连续的??
是重新new了一个把str和word放进去还是别的什么?

解决方案 »

  1.   

    String类支持静态(不变的)的字符串。StringBuffer类则支持可修改的字符串。
    用String类创建的字符串是只读的。
    当使用“+”运算符将一些字符加到某String对象上时,结果产生了新的对象,而不是原来String对象的一个修改值。
    例:
      String str1 = "abc",str2;
      BufferString bfs = new BufferString("abc");
      str2 = str1+"d";//now str1 is "abc" ;str2 is "abcd"
      bfs.append("d");// now bfs is "abcd"
      

  2.   

    StringBuffer就是重新生成了个新的对象,和""+str一样
      

  3.   

    最重要的是一般来说StringBuffer的append执行效果要远高于String的+号(当然也有特殊情况),特别是在循环体内。
      

  4.   

    如上所说,在涉及到字符运算时,最好使用StringBuffer
      

  5.   

    最重要的是一般来说StringBuffer的append执行效果要远高于String的+号(当然也有特殊情况),特别是在循环体内
    因为String 每次进行 + 操作,都会生成2个新的对象。浪费资源!影响效率特别是在面试的时候
      

  6.   

    昨天晚上看到一片有关的解说
    说+ 是在编译前连接也就是说如String s = "abcd"+"efg"+"hrjk"编译后就直接生成"abcdefghrjk" 了 而StringBuffer的append是在运行期间追加的!
    1 :+操作符会为字符串连接提供最佳的性能——当字符串是在编译期决定的时候。
    2 :如果字符串在运行期决定,使用一个合适的初期容量值初始化的StringBuffer会为字符串连接提供最佳的性能
      

  7.   

    字符串内存分配方式不同,如果内存资源受限或者要提高代码执行效率,最好使用StringBuffer方式
      

  8.   

    String str1 = "hello";
    String str2 = "world";
    String str3 = "str1";
    String str1 = str1 + str2;//String 赋值实际上这个是NEW了一个新的对象了,str1变了
    System.out.println(str3);//str3没有变,这是因为str3指向的地址还是最早的str1所在的地址
    这里所做的内部操作,其实不是把str1的内容改变为原str1+str2的内容这么简单, 而把创建一个新的String, 内容为str1 + str2的内容,然后再把str1这个引用重新指向新创建的String, 而str3还指向最早的str1地址,并且内容还是"hello".而如果是StringBuffer的话,则直接更改str1的内容,而不是先创建一个新的StringBuffer.
    StringBuffer b1=new StringBuffer("hello");
    StringBuffer b2=b1;
    b2.append("world");//StringBuffer赋值,操作b2还是那个对象
    System.out.println(b1);String对象是不可变对象,一旦创建之后就不能再被改变,StringBuffer对象则是可变对象,可变对象则可以在创建之后被改变.为获得更佳的性能你需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。String 是一种非常常用的数据类型,但由于 String 是不可变对象,在进行 String 的相关操作的时候会产生许多临时的 String 对象。
    而 StringBuffer 在操作上是在一个缓冲中进行的,性能当然优越得多。
    不过,一般做为简单的字符串传递和其它操作,只不要改变字符串内容的操作,用 String 效率会高一些。
      

  9.   

    Java虚拟机会维护一个内部的滞留字符串对象的列表(字符串的常量池)来避免在堆内存中产生重复的 String对象。当JVM从class文件里加载字符串字面量并执行的时候,它会先检查一下当前的字符串是否已经存在于滞留字符串列表,如果已经存在,那就不会再创建一个新的String对象而是将引用指向已经存在的String对象,JVM会在内部为字符串字面量作这种检查,但并不会为通过new关键字创建的String对象作这种检查。当然你可以明确地使用String.intern()方法强制JVM为通过 new关键字创建的String对象作这样的检查。这样可以强制JVM检查内部列表而使用已有的String对象。
      所以结论是,JVM会内在地为字符串字面量维护一些唯一的 String对象,程序员不需要为字符串字面量而发愁,但是可能会被一些通过 new关键字创建的String对象而困扰,不过他们可以使用intern ()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。
      同一个字符串对象被重复地创建是不必要的,String.intern ()方法可以避免这种情况。String.intern()方法检查字符串对象的存在性,如果需要的字符串对象已经存在,那么它会将引用指向已经存在的字符串对象而不是重新创建一个。StringTest2.java
     
    package com.performance.string;
    // This class shows the use of intern() method to improve performance
    public class StringTest2 {
    public static void main(String[] args){
        // create String references like s1,s2,s3...so on..
        String variables[] = new String[50000];
        for( int i=0;i<variables.length;i++){
            variables[i] = "s"+i;
        }
        // create String literals
        long startTime0 = System.currentTimeMillis();
        for(int i=0;i<variables.length;i++){
            variables[i] = "hello";
        }
        long endTime0 = System.currentTimeMillis();
        System.out.println("Time taken for creation of String literals : "
                             + (endTime0 - startTime0) + " milli seconds" );
        // create String objects using 'new' keyword       
        long startTime1 = System.currentTimeMillis();
        for(int i=0;i<variables.length;i++){
            variables[i] = new String("hello");
        }
        long endTime1 = System.currentTimeMillis();
        System.out.println("Time taken for creation of String objects with 'new' key word : "
                            + (endTime1 - startTime1)+" milli seconds");
        // intern String objects with intern() method   
        long startTime2 = System.currentTimeMillis();
        for(int i=0;i<variables.length;i++){
            variables[i] = new String("hello");
            variables[i] = variables[i].intern();
        }
        long endTime2 = System.currentTimeMillis();
        System.out.println("Time taken for creation of String objects with intern(): "
                            + (endTime2 - startTime2)+" milli seconds");
        }
    }
    这是上面那段代码的输出结果:
    Time taken for creation of String literals : 0 milli seconds
    Time taken for creation of String objects with 'new' key word : 160 milli seconds
    Time taken for creation of String objects with intern(): 60 milli seconds可以使用+操作符或者String.concat()或者StringBuffer.append()等办法来连接多个字符串,那一种办法具有最佳的性能呢?
      如何作出选择取决于两种情景,第一种情景是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情景是你使用的是 StringBuffer还是String。通常StringBuffer.append()方法会优于+操作符或 String.concat()方法,但是在一些特定的情况下这个假想是不成立的。
      

  10.   

    1) 第一种情景:编译期决定
    请看下面的StringTest3.java代码和输出结果。package com.performance.string;
    /** This class shows the time taken by string concatenation at compile time and run time.*/
    public class StringTest3 {
      public static void main(String[] args){
        //Test the String Concatination
        long startTime = System.currentTimeMillis();
        for(int i=0;i<5000;i++){
        String result = "This is"+ "testing the"+ "difference"+ "between"+
                "String"+ "and"+ "StringBuffer";
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Time taken for string concatenation using + operator : "
             + (endTime - startTime)+ " milli seconds");
        //Test the StringBuffer Concatination
        long startTime1 = System.currentTimeMillis();
        for(int i=0;i<5000;i++){
        StringBuffer result = new StringBuffer();
             result.append("This is");
            result.append("testing the");
            result.append("difference");
            result.append("between");
           result.append("String");
           result.append("and");
           result.append("StringBuffer");
         }
        long endTime1 = System.currentTimeMillis();
        System.out.println("Time taken for String concatenation using StringBuffer : "
               + (endTime1 - startTime1)+ " milli seconds");
      }
    }
    这是上面的代码的输出结果:
    Time taken for String concatenation using + operator : 0 milli seconds
    Time taken for String concatenation using StringBuffer : 50 milli seconds
    很有趣地,+操作符居然比StringBuffer.append()方法要快,为什么呢?
     
      这里编译器的优化起了关键作用,编译器像下面举例的那样简单地在编译期连接多个字符串。它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。
     
    编译前:
    String result = "This is"+"testing the"+"difference"+"between"+"String"+"and"+"StringBuffer";
    编译后:
    String result = "This is testing the difference between String and StringBuffer";这里String对象在编译期就决定了,而StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作用于字符串的值可以预先知道的时候,下面是一个例子。
     
    编译前:
    public String getString(String str1,String str2) {
        return str1+str2;
    }
    编译后:
    return new StringBuffer().append(str1).append(str2).toString();
    运行期决定需要更多的时间来运行。
     
    2) 第二种情景:运行期决定
    看看下面的代码你会发现与情景一相反的结果——连接多个字符串的时候StringBuffer要比String快。
    StringTest4.java
     
    package com.performance.string;
    /** This class shows the time taken by string concatenation
    using + operator and StringBuffer  */
    public class StringTest4 {
     public static void main(String[] args){
        //Test the String Concatenation using + operator
        long startTime = System.currentTimeMillis();
        String result = "hello";
        for(int i=0;i<1500;i++){
            result += "hello";
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Time taken for string concatenation using + operator : "
                      + (endTime - startTime)+ " milli seconds");
        //Test the String Concatenation using StringBuffer
        long startTime1 = System.currentTimeMillis();
        StringBuffer result1 = new StringBuffer("hello");
        for(int i=0;i<1500;i++){
            result1.append("hello");
        }
        long endTime1 = System.currentTimeMillis();
        System.out.println("Time taken for string concatenation using StringBuffer :  "
                      + (endTime1 - startTime1)+ " milli seconds");
        }
    }
    这是上面的代码的输出结果:
    Time taken for string concatenation using + operator : 280 milli seconds
    Time taken for String concatenation using StringBuffer : 0 milli seconds
    看得出StringBuffer.append()方法要比+操作符要快得多,原因是两者都是在运行期决定字符串对象。
    关键点
    1. 无论何时只要可能的话使用字符串字面量来常见字符串而不是使用new关键字来创建字符串。
    2. 无论何时当你要使用new关键字来创建很多内容重复的字符串的话,请使用String.intern()方法。
    3. +操作符会为字符串连接提供最佳的性能——当字符串是在编译期决定的时候。
    4. 如果字符串在运行期决定,使用一个合适的初期容量值初始化的StringBuffer会为字符串连接提供最佳的性能。
      

  11.   

    字符串的串联,对于每“一串”串联,例如"abc" + str + "def" + str_1 + ....
    编译时,实际上是翻译为:
    StringBuffer sb = new StringBuffer();
    sb.append("abc");
    sb.append(str);
    ....
    最后调用sb.toString()因此,如果只是一个串联,那么直接用+号就可以了,性能没有差别,代码更简单。
    但是如果在循环中使用+号来串联,因为每次串联都会被翻译为上面的代码,导致创建了很多StringBuffer对象实例,所以会慢得多。