Java基础知识强化47:StringBuffer类之StringBuffer的三个面试题

1. 面试题:String,StringBuffer,StringBuilder的区别 ?

答:String是字符串内容不可变的,而StringBuffer和StringBuilder是字符串内容长度可变的;

      StringBuffer是同步的,数据安全,效率低。

      StringBuilder是不同步的,数据不安全,效率高。

(1). 在执行速度方面的比较:StringBuilder > StringBuffer
(2). StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
(3). StringBuilder:线程非安全的
        StringBuffer:线程安全的
      当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:• 如果要操作少量的数据用 = String
                  • 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
                  • 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

注意:为什么StringBuffer具有数据安全的特性?

答:观察源码,如下:

  1 /*
  2  * @(#)StringBuffer.java    1.101 05/11/17
  3  *
  4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6  */
  7 
  8 package java.lang;
  9 
 10 
 11 /**
 12  * A thread-safe, mutable sequence of characters. 
 13  * A string buffer is like a {@link String}, but can be modified. At any 
 14  * point in time it contains some particular sequence of characters, but 
 15  * the length and content of the sequence can be changed through certain 
 16  * method calls.
 17  * <p>
 18  * String buffers are safe for use by multiple threads. The methods 
 19  * are synchronized where necessary so that all the operations on any 
 20  * particular instance behave as if they occur in some serial order 
 21  * that is consistent with the order of the method calls made by each of 
 22  * the individual threads involved.
 23  * <p>
 24  * The principal operations on a <code>StringBuffer</code> are the 
 25  * <code>append</code> and <code>insert</code> methods, which are 
 26  * overloaded so as to accept data of any type. Each effectively 
 27  * converts a given datum to a string and then appends or inserts the 
 28  * characters of that string to the string buffer. The 
 29  * <code>append</code> method always adds these characters at the end 
 30  * of the buffer; the <code>insert</code> method adds the characters at 
 31  * a specified point. 
 32  * <p>
 33  * For example, if <code>z</code> refers to a string buffer object 
 34  * whose current contents are "<code>start</code>", then 
 35  * the method call <code>z.append("le")</code> would cause the string 
 36  * buffer to contain "<code>startle</code>", whereas 
 37  * <code>z.insert(4, "le")</code> would alter the string buffer to 
 38  * contain "<code>starlet</code>". 
 39  * <p>
 40  * In general, if sb refers to an instance of a <code>StringBuffer</code>, 
 41  * then <code>sb.append(x)</code> has the same effect as 
 42  * <code>sb.insert(sb.length(), x)</code>.
 43  * <p>
 44  * Whenever an operation occurs involving a source sequence (such as
 45  * appending or inserting from a source sequence) this class synchronizes
 46  * only on the string buffer performing the operation, not on the source.
 47  * <p>
 48  * Every string buffer has a capacity. As long as the length of the 
 49  * character sequence contained in the string buffer does not exceed 
 50  * the capacity, it is not necessary to allocate a new internal 
 51  * buffer array. If the internal buffer overflows, it is 
 52  * automatically made larger. 
 53  *
 54  * As of  release JDK 5, this class has been supplemented with an equivalent 
 55  * class designed for use by a single thread, {@link StringBuilder}.  The 
 56  * <tt>StringBuilder</tt> class should generally be used in preference to 
 57  * this one, as it supports all of the same operations but it is faster, as 
 58  * it performs no synchronization.
 59  *
 60  * @author    Arthur van Hoff
 61  * @version     1.101, 11/17/05
 62  * @see     java.lang.StringBuilder
 63  * @see     java.lang.String
 64  * @since   JDK1.0
 65  */
 66  public final class StringBuffer
 67     extends AbstractStringBuilder
 68     implements java.io.Serializable, CharSequence
 69 {
 70 
 71     /** use serialVersionUID from JDK 1.0.2 for interoperability */
 72     static final long serialVersionUID = 3388685877147921107L;
 73 
 74     /**
 75      * Constructs a string buffer with no characters in it and an 
 76      * initial capacity of 16 characters. 
 77      */
 78     public StringBuffer() {
 79     super(16);
 80     }
 81 
 82     /**
 83      * Constructs a string buffer with no characters in it and 
 84      * the specified initial capacity. 
 85      *
 86      * @param      capacity  the initial capacity.
 87      * @exception  NegativeArraySizeException  if the <code>capacity</code>
 88      *               argument is less than <code>0</code>.
 89      */
 90     public StringBuffer(int capacity) {
 91     super(capacity);
 92     }
 93 
 94     /**
 95      * Constructs a string buffer initialized to the contents of the 
 96      * specified string. The initial capacity of the string buffer is 
 97      * <code>16</code> plus the length of the string argument.
 98      *
 99      * @param   str   the initial contents of the buffer.
100      * @exception NullPointerException if <code>str</code> is <code>null</code>
101      */
102     public StringBuffer(String str) {
103     super(str.length() + 16);
104     append(str);
105     }
106 
107     /**
108      * Constructs a string buffer that contains the same characters
109      * as the specified <code>CharSequence</code>. The initial capacity of
110      * the string buffer is <code>16</code> plus the length of the
111      * <code>CharSequence</code> argument.
112      * <p>
113      * If the length of the specified <code>CharSequence</code> is
114      * less than or equal to zero, then an empty buffer of capacity
115      * <code>16</code> is returned.
116      *
117      * @param      seq   the sequence to copy.
118      * @exception NullPointerException if <code>seq</code> is <code>null</code>
119      * @since 1.5
120      */
121     public StringBuffer(CharSequence seq) {
122         this(seq.length() + 16);
123         append(seq);
124     }
125 
126     public synchronized int length() {
127     return count;
128     }
129 
130     public synchronized int capacity() {
131     return value.length;
132     }
133 
134 
135     ...

因为很多方法都是synchronized 

2. 面试题:StringBuffer 和数组的区别?

答:二者都可以看出是一个容器,装其他的数据。但是呢,StringBuffer的数据最终是一个字符串数据,而数组可以放置任意类型的同一种数据。

3. 面试题:形式参数问题。

String作为参数传递

StringBuffer作为参数传递

   形式参数:

               基本类型:形式参数的改变不影响实际参数

               引用类型:形式参数的改变直接影响实际参数

案例演示:

package cn.itcast_08;

/*
 * 形式参数问题:
 * String作为参数传递
 * StringBuffer作为参数传递 
 * 
 * 形式参数:
 *         基本类型:形式参数的改变不影响实际参数
 *         引用类型:形式参数的改变直接影响实际参数
 * 
 * 注意:
 *         String作为参数传递,效果和基本类型作为参数传递是一样的。
 */
public class StringBufferDemo {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        System.out.println(s1 + "---" + s2);// hello---world
        change(s1, s2);
        System.out.println(s1 + "---" + s2);// hello---world

        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("world");
        System.out.println(sb1 + "---" + sb2);// hello---world
        change(sb1, sb2);
        System.out.println(sb1 + "---" + sb2);// hello---worldworld

    }

    public static void change(StringBuffer sb1, StringBuffer sb2) {
        sb1 = sb2;
        sb2.append(sb1);
    }

    public static void change(String s1, String s2) {
        s1 = s2;
        s2 = s1 + s2;
    }
}

运行效果如下:

原文地址:https://www.cnblogs.com/hebao0514/p/4822262.html