/******************************************************************************
 * Print the reference of a String object while being manipulated
 ******************************************************************************/
public class zStringRef
{
    public static void main (String[] args) 
    {
        System.out.println(">> Initial value of String...");
        String X = "Hello World";
        printRef(X,"X","");
        System.out.println();

        System.out.println(">> Assigning to another string...");
        String Y = X;												//same location
        printRef(Y,"Y","");
        System.out.println();

        System.out.println(">> Making a change to Y...");
        Y = "Goodbye World";										//Y is now at a different location
        printRef(X,"X","");
        printRef(Y,"Y","");											//X location remain the same
        System.out.println();

        System.out.println(">> Concatenate without reassignment");
        Y.concat(" Again");
        printRef(Y,"Y","");

        System.out.println(">> Concatenate with reassignment");
        Y = Y.concat(" Again");
        printRef(Y,"Y","");

        System.out.println();
        String Z = changeValue(X);									//calling the method
        System.out.println();

        System.out.println(">> AFTER THE METHOD...");
        printRef(Z,"Z","");
        printRef(X,"X","");
    }
    static String changeValue(String A)
    {
        System.out.println("    >> IN THE METHOD...");
        printRef(A,"A","    ");
        
        System.out.println("    >> Making a change to A...");
        A = "Adios World";
        printRef(A,"A","    ");
 
        System.out.println("    >> Making another change to A...");
        A = "Goodbye World";
        printRef(A,"A","    ");

        return A;
    }
    static void printRef(String str, String name, String indent)
    {
        System.out.printf("%s String %s=%-25s is at reference: %d %4$x \n", indent, name, str, System.identityHashCode(str) );
    }
}