«^»
2.6. Objects

2.6.1. Reference variables

Besides the primitive types that can be used for simple values, we often want to represent structured values. For example, we might want to represent a date in history, a point in two-dimensional space, and so on. In Java, a variable that is of a reference type is used to refer to a structured value.

For example, in order to represent a point in two-dimensional space, the package java.awt provides a ‘class declaration’ called Point. Such a class declaration automatically provides a reference type called Point, and we can declare a variable called myPoint to be of this reference type by the declaration:

0109: java.awt.Point myPoint;
To avoid having to repeat the package name every time we want to use Point, we can use an import declaration at the start of the file containing the Java source code:
0110: import java.awt.Point;
Having done this, we can declare the variable myPoint by:
0111: Point myPoint;

Such a declaration only introduces a reference variable, a variable that can refer to an object that contains the details about the point.

In some ways, a reference variable is like a pointer variable in Pascal, C or C++.

2.6.2. Creating an object

Having declared the reference variable, we ought to get it to refer to a Point object. This is done by using an assignment statement where the RHS contains a class instance creation expression:

0112: myPoint = new Point(100,200);
The creation expression new Point(100,200) uses a ‘constructor’ for the class Point to create an object of that class with x and y fields of 100 and 200. We will see later that we can do this because this kind of constructor has been provided by the designers of the java.awt package. Often a class provides several different constructors, e.g., as well as a constructor that has two parameters which are the x and y coordinates, the designers of the class Point could also have provided a constructor to construct a Point from a String:
0113: myPoint = new Point("100:200");
but they chose not to do this.

So we now have a variable called myPoint that refers to a point that has the x and y coordinates 100 and 200.

The above declaration of myPoint together with the above assignment statement can be shortened to a declaration that has an initializer:

0114: Point myPoint = new Point(100,200);

2.6.3. Referring to the fields of an object

We can use the dot notation to refer to the fields of an object, e.g., we can use myPoint.x and myPoint.y. For example, we could change the point being represented by 10 units in the x direction and 20 units in the y direction by the assignment statements:

0115: myPoint.x += 10;
0116: myPoint.y += 20;

Note that this is a little different to the languages Pascal, C and C++ where some extra syntax is used to say that we are dereferencing a pointer.

2.6.4. Applying methods to an object

The designers of the java.awt package have thought that we may want to move an existing point to a new point in space, and so they have provided a method to do this. A method is what would be called a function or procedure in other programming languages. The method that they have provided is called translate. So, instead of the above two assignment statements, we could write:

0117: myPoint.translate(10,20);
Note that the dot notation that we used above to refer to the two fields of a Point object is also used in the call of a method. You should look at this call in the following way: ‘apply the translate method with arguments 10 and 20 to the myPoint object’. Note: you would have written something like: translate(myPoint,10,20) in languages like Pascal and C.

2.6.5. Copying objects

Suppose we have:

0118: Point otherPoint;
0119: otherPoint = myPoint;
The assignment statement causes otherPoint to refer to the same object that myPoint refers to.

So, the above assignment statement does not produce a clone. The classes of the Core APIs use two different ways of enabling you to produce a clone of an object:

Although Point does not provide a clone method, it does provide a suitable constructor:
0120: Point clonePoint;
0121: clonePoint = new Point(myPoint);

2.6.6. Comparing objects

The == operator in the following condition is asking whether the two reference variables refer to the same object:

0122: if ( myPoint == otherPoint ) { ... } else { ... }

If, instead, you want to ask whether the two objects referred to by two reference variables have the same value, you can often use a method called equals:
0123: if ( myPoint.equals(clonePoint) ) { ... } else { ... }

2.6.7. The value null

If a reference variable has the value null, then this means that the variable does not currently refer to any object. An assignment statement can be used to indicate this:

0124: myPoint = null;

And you can test whether a reference variable does not refer to an object:
0125: if ( myPoint == null ) { ... } else { ... }
Note: whilst null appears to be a keyword of the language, it is technically the null literal.

2.6.8. Garbage collection

Pascal/C/C++ programs inadvertently dispose/free/delete objects which are still in use:

0126: var p, q:^integer;    int *p, *q;                 int *p, *q;
0127: new(p);               p = malloc(sizeof(int));    p = new int;
0128: p^ := 27;             *p = 27;                    *p = 27;
0129: q := p;               q = p;                      q = p;
0130: dispose(p);           free(p);                    delete p;
0131: writeln(q^);          printf("%d\n", *q);         cout << *q << endl;
And programs often cause memory leaks by not using dispose/free/delete on unwanted objects.

In Java, you do not delete objects: instead, Java has garbage collection. The garbage collector detects objects no longer in use, and reuses their space. Also, unlike C++, you do not have to provide destructors for classes.