"Hi, Amigo, it's me again, Ellie. Sorry for saying that over and over again, but it's customary on the Earth in the 31st century. I'd like to give you more details about reference variables and passing reference variables to functions (methods)."

"I'm ready."

"Great, then listen. Reference variables are any non-primitive variables. Such variables only contain an object reference (a reference to an object)."

"Primitive variables contain values, while reference variables store references to objects or null. Am I right?"

"Absolutely."

"What's a reference?"

"The relationship between an object and an object reference is like the relationship between a person and her phone number. The phone number isn't the person, but it can be used to call the person, ask for some information, manage her, or give orders. A reference is also used to work with objects. All objects interact with one another using references."

"As if they were talking to each other over the phone?"

"Exactly. When a primitive variable is assigned, the value is copied. If a reference is assigned, only the address of the object (the phone number) is copied. The object itself isn't copied."

"OK, I got it."

"A reference gives you one more benefit: you can pass an object reference to any method, and that method will be able to use the reference to modify (change) the object by calling its methods and accessing data inside the object."

Example 1
The values m and n don't change here.
public class References
{
  public static void main (String[] args)
  {
    int m = 5;
    int n = 6;

    System.out.println("M=" + m + " N=" + n);
    swap(m, n);
    System.out.println("M=" + m + " N=" + n);
  }

  private static void swap(int a, int b)
  {
    int c = a;
    a = b;
    b = c;
  }
}
And here's why.
This code is analogous to the code on the left
public class References
{
  public static void main (String[] args)
  {
    int m = 5;
    int n = 6;

    System.out.println("M=" + m + " N=" + n);
    int a = m, b = n;

    int c = a;
    a = b;
    b = c;

    System.out.println("M=" + m + " N=" + n);
  }
}

"Only the values 5 (m) and 6 (n), respectively, are assigned to variables a and b; a and b know nothing about (and don't influence in any way) m and n."

"To tell you the truth, I now realize that I didn't understand anything. Can you give me a few more examples?"

"With an object reference, we could have done the following:"

Example 2
The objects' data changes in this code
public class Primitives
{
  public static void main(String[] args)
  {
    Student jen = new Student();
    jen.name = "Jen";
    jen.age = 21;

    Student beth = new Student();
    beth.name = "Beth";
    beth.age = 15;

    System.out.println("Jen is " + jen.age);
    System.out.println("Beth is " + beth.age);

    ageSwap(jen, beth);

    System.out.println("Jen is " + jen.age);
    System.out.println("Beth is " + beth.age);
  }

  private static void ageSwap(Student a,
                                    Student b)
  {
    int c = a.age;
    a.age = b.age;
    b.age = c;
  }

  static class Student
  {
    String name;
    int age;
  }
}
And here's why.
This code is analogous to the code on the left
public class Primitives
{
  public static void main(String[] args)
  {
    Student jen = new Student();
    jen.name = "Jen";
    jen.age = 21;

    Student beth = new Student();
    beth.name = "Beth";
    beth.age = 15;

    System.out.println("Jen is " + jen.age);
    System.out.println("Beth is " + beth.age);

    Student a = jen, b = beth;

    int c = a.age;
    a.age = b.age;
    b.age = c;

    System.out.println("Jen is " + jen.age);
    System.out.println("Beth is " + beth.age);
  }





  static class Student
  {
    String name;
    int age;
  }
}

"References to jen and beth, respectively, are assigned to the variables a and b; a and b change the values inside the objects jen and beth."

"And you can declare classes inside of other classes, right? Cool!"

"But I still don't understand everything else very well."

"All in due time."