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; } }
运行效果如下: