// ----------------------------------------------------------------------------- // StringBufferDemo.java // ----------------------------------------------------------------------------- /* * ============================================================================= * Copyright (c) 1998-2011 Jeffrey M. Hunter. All rights reserved. * * All source code and material located at the Internet address of * http://www.idevelopment.info is the copyright of Jeffrey M. Hunter and * is protected under copyright laws of the United States. This source code may * not be hosted on any other site without my express, prior, written * permission. Application to host any of the material elsewhere can be made by * contacting me at jhunter@idevelopment.info. * * I have made every effort and taken great care in making sure that the source * code and other content included on my web site is technically accurate, but I * disclaim any and all responsibility for any loss, damage or destruction of * data or any other property which may arise from relying on it. I will in no * case be liable for any monetary damages arising from such loss, damage or * destruction. * * As with any code, ensure to test this code in a development environment * before attempting to run it in production. * ============================================================================= */ /** * ----------------------------------------------------------------------------- * Java provides two classes: String and StringBuffer. The String class is used * to store and manipulate character strings that cannot be changed. Another * way of describing this is to say that Strings are read only and immutable. * The StringBuffer class, on the other hand, is used to represent characters * that can be modified. * * The significant difference between these two classes is performance where * StringBuffer is faster than String when performing simple concatenations. * When a String is being manipulated in code, character string are routinely * concatenated like shown in the following example: * * String name = new String("Alex"); * name += ", Hunter"; * * Now consider the same concatenation, but using a StringBuffer: * * StringBuffer name = new StringBuffer("Alex"); * name.append(", Hunter"); * * Now to many developers, the examples above may seem very similar. The + * operator appears innocent, but the code generated may produce some surprises. * Using a StringBuffer for concatenation can in fact produce code that is * significantly faster than using a String. To discover why this is the case, * lets examine the generated bytecode from our two examples. The bytecode for * the example using String looks like this: * * % javap -c t * * Compiled from t.java * public class t extends java.lang.Object { * public t(); * public static void main(java.lang.String[]); * } * * Method t() * 0 aload_0 * 1 invokespecial #1 * 4 return * * Method void main(java.lang.String[]) * 0 new #2 * 3 dup * 4 ldc #3 * 6 invokespecial #4 * 9 astore_1 * 10 new #5 * 13 dup * 14 invokespecial #6 * 17 aload_1 * 18 invokevirtual #7 * 21 ldc #8 * 23 invokevirtual #7 * 26 invokevirtual #9 * 29 astore_1 * 30 return * * The bytecode at locations 0 through 9 is executed for the first line of code, * namely: * * String name = new String("Alex"); * * Then, the bytecode at location 10 through 29 is executed for the * concatenation: * * name += ", Hunter"; * * Here is where things get interesting. The bytecode generated for the * concatenation creates a StringBuffer object, then invokes its append method: * the temporary StringBuffer object is created at location 10, and its append * method is called at location 23. Because the String class is immutable, a * StringBuffer must be used for concatenation. * * After the concatenation is performed on the StringBuffer object, it must be * converted back into a String. This is done with the call to the toString * method at location 26. This method creates a new String object from the * temporary StringBuffer object. The creation of this temporary StringBuffer * object and its subsequent conversion back into a String object are very * expensive. * * In summary, the two lines of code above result in the creation of three * objects: * * 1.) A String object at location 0 * 2.) A StringBuffer object at location 10 * 3.) A String object at location 26 * * Now, let's look at the bytecode generated for the example using StringBuffer: * * % javap -c t * * Compiled from t.java * public class t extends java.lang.Object { * public t(); * public static void main(java.lang.String[]); * } * * Method t() * 0 aload_0 * 1 invokespecial #1 * 4 return * * Method void main(java.lang.String[]) * 0 new #2 * 3 dup * 4 ldc #3 * 6 invokespecial #4 * 9 astore_1 * 10 aload_1 * 11 ldc #5 * 13 invokevirtual #6 * 16 pop * 17 return * * The bytecode at locations 0 to 9 is executed for the first line of code: * * StringBuffer name = new StringBuffer("Alex"); * * The bytecode at location 10 to 16 is then executed for the concatenation: * * name.append(", Hunter"); * * Notice that, as is the case in the first example, this code invokes the * append method of a StringBuffer object. Unlike the first example, however, * there is no need to create a temporary StringBuffer and then convert it into * a String object. This code creates only one object, the StringBuffer, at * location 0. * * To summarize, StringBuffer concatenation is significantly faster than String * concatenation. Obviously, StringBuffers should be used in this type of * operation when possible. If the functionality of the String class is desired, * consider using a StringBuffer for concatenation and then performing one * conversion to String. * ----------------------------------------------------------------------------- * @version 1.0 * @author Jeffrey M. Hunter (jhunter@idevelopment.info) * @author http://www.idevelopment.info * ----------------------------------------------------------------------------- */ public class StringBufferDemo { public static void main(String[] args) { StringBuffer name = new StringBuffer("Alex"); name.append(", Hunter"); // One way to convert a StringBuffer to a String String nameStr1 = name.toString(); // Allocates a new string that contains the sequence of characters // currently contained in the string buffer argument. String nameStr2 = new String(name); System.out.println("name : " + name); System.out.println("nameStr1 : " + nameStr1); System.out.println("nameStr2 : " + nameStr2); } }