/****************************************************************************************
 * Show the difference between pass-by-value and pass-by-reference
 *
 * A primitive type is passed-by-value      (cannot be changed in called method)
 * A String    type is passed-by-reference  (if changed in method, you get a new String object)
 * An object   type is passed-by-reference  (can be changed in called method)
 *
 *****************************************************************************************/
public class passBy
{
    public static void main (String[ ] args)
    {        
        int num  = 5;                                       //create a primitive
        String name1       = new String("hello");           //create a String object
        StringBuffer name2 = new StringBuffer("goodbye");   //create a StringBuffer object
    
        System.out.println("\t\t\t\t       int      String       StringBuffer");
        System.out.println("\t\t\t\t    -------------------------------------");

        System.out.println("In main, sent to method.......: \t" + num +"\t"+ name1 +"\t\t"+ name2);

        System.out.print("\t\t    reference.: \t\t" + reference(name1) );    //print the reference 
        System.out.print("\t"                       + reference(name2) ); 
        System.out.println("\n"); 

        passByTest(num, name1, name2);                                       //call the passByTest method

        System.out.println("In main, after the method.....: \t" + num +"\t"+ name1 +"\t\t"+ name2);

        System.out.print("\t\t    reference.: \t\t" + reference(name1) );    //print the reference 
        System.out.print("\t"                       + reference(name2) ); 
        System.out.println("\n"); 
    }

   /****************************************************************************************
    * A passBy method to test how parameters are passed
    *
    * @param  num   - type int          - a primitive integer number
    * @param  name1 - type String       - an object which is a String type
    * @param  name2 - type StringBuffer - an object which is a StringBuffer type
    * @return void 
    ****************************************************************************************/
    static void passByTest(int num, String name1, StringBuffer name2)    //Get an int, a String, a StringBuffer      
    {
        System.out.println("....In method, data received..: \t" + num +"\t"+ name1 +"\t\t"+ name2);
    
        System.out.print("\t\t    reference.: \t\t" + reference(name1) );    //print the reference 
        System.out.print("\t"                       + reference(name2) ); 
        System.out.println("\n"); 

        num += 10;                                      //change the number
        name1 += " world";                              //change the String
        name2.append(" world");                         //change the StringBuffer

        System.out.println("....In method, data changed to: \t" + num +"\t"+ name1 +"\t"+ name2);

        System.out.print("\t\t    reference.: \t\t" + reference(name1) );    //print the reference 
        System.out.print("\t"                       + reference(name2) ); 
        System.out.println("\n"); 
    }

   /****************************************************************************************
    * Return a reference value for an object
    ****************************************************************************************/
    static String reference(Object obj)                   
    {
        int    i   = System.identityHashCode(obj);      //the reference as an integer
        String ref = Integer.toHexString(i);            //the reference as hex 
        return ref;
    }
}