Objects and References
An Introduction with Examples in Java |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
boolean
, double
,
int
,... that don't have constituent parts
null
:
null
can be used to indicate that
a reference variable does not refer to anything.
Operator
main()
)
// Add the name d to the name table, allocate eight bytes of // memory (since doubles use eight bytes), and associate the // allocated memory with that name. // double d; // Put the value 5.0 in the eight bytes of memory // that are associated with the name d. // d = 5.0;
main()
)
// Add the name c to the name table, allocate four bytes of // memory (since addresses use four bytes), and associate the // allocated memory with that name. // Color c; // Allocate 12 bytes of memory to hold the three int // attributes in the Color object and put the int values in // that memory. Then, put the address in the four bytes // associated with the variable named c. // c = new Color( 69, 0, 132);
new
operator is invokeString
literals
(i.e., it stores only one copy of a specific String
)
new
Operator and Memorylength
attribute
at that addressNote About the Heap, Literals space, and Class space: We will sometimes worry about the size of entities and work directly with the bytes and will sometimes work with larger entities and not worry about the bytes they occupy.
In this example (from a fragment of main()
), memory is
allocated for a Color
object each iteration. (Reminder:
A Color
object has three int
attributes,
named red
, green
, and
blue
.)
int i, n; // Compile-Time Color c; // Compile-Time n = 3; for (i=0; i < n; i++) { c = new Color(i, i, i); // Run-Time }
Note: In this example we are not worrying about the size of the three
int
attributes in the Color
objects.
final
Variablesfinal
Variables:
final
The following example (from a fragment of main()
) uses
the assignment operator both during the instantiation of an object
and to create an alias.
Color c, d; // The left-hand-side is a reference variable so // the right-hand-side must be (and is) a // memory address c = new Color(102, 102, 0); // The memory address on the right-hand-side is // assigned to the reference variable on the // left-hand-side // d = c;
public class Pair { public int a, b; }
In the following example (from a fragment
of main()
), p
and q
refer to
the same object so changing the attributes of one changes the
attributes of "the other".
Pair p, q; // The left-hand-side is a reference type so the right-hand-side // must be (and is) a reference p = new Pair(); p.a = 10; // The left-hand-side is a primitive type p.b = 20; // The left-hand-side is a primitive type // The memory address on the right-hand-side is assigned to the // reference type variable on the left-hand-side // q = p; q.a = 99; // Change the value of the attribute a in the Pair // that is referred to by q System.out.println(p.a);
public class Customer { public int id; } public class Account { public Customer holder; public double balance; }
Account a, d, s, o; Customer wilma; // Instantiate the Customer wilma = new Customer(); wilma.id = 1; // Instantiate the original Account object o = new Account(); o.holder = wilma; o.balance = 100.00; // a is an alias for o a = o; // s is a shallow copy of o s = new Account(); s.holder = o.holder; s.balance = o.balance; // d is a deep copy of o d = new Account(); d.holder = new Customer(); d.holder.id = o.holder.id; d.balance = o.balance;
The relational equals operator (i.e., ==
) can be used
with reference types, and it is sometimes necessary to do so, but you must
understand that it compares two references.
Color a, b, c; a = new Color(153, 0, 102); b = a; c = new Color(153, 0, 102); // Compare the references a, b, and c // if (a == b) System.out.println("a and b are aliases"); if (a == c) System.out.println("a and c are aliases"); if (b == c) System.out.println("b and c are aliases");
==
operator compares references.equals()
method for this purpose// Compare the R,G,B values in a, b, and c // if (a.equals(b)) System.out.println("a and b have the same RGB values"); if (a.equals(c)) System.out.println("a and c have the same RGB values"); if (b.equals(c)) System.out.println("b and c have the same RGB values");
String
Literals
String
literals are reference types, but the compiler
can be smart and store only one instance of each (a process called
"interning").
String s, t, u; s = "James Madison University"; t = s; u = "James Madison University"; // This will, not surprisingly, print "Same contents" if (s.equals(u)) System.out.println("Same contents"); // This will, not surprisingly, print "Same reference" if (s == t) System.out.println("Same reference"); // This may, somewhat surprisingly, print "Same reference" // but you shouldn't rely on it if (s == u) System.out.println("Same reference");
String
"
Since String
objects are reference types, a String
variable can contain the reference null
.
String s; s = null;
This is not the same thing as what is sometimes called the
"null String
" (and sometimes, perhaps less ambiguously, called
the "empty String
").
String t; t = "";
Consider the following example:
double unitCircumference; unitCircumference = 2.0 * Math.PI;
and recall that the Math
class has two static
double
attributes, E
and PI
.
Note that the address of c
changes every iteration. Hence
the memory that was allocated in the previous iteration becomes garbage.
int i, n; // Compile-Time Color c; // Compile-Time n = 3; for (i=0; i < n; i++) { c = new Color(i, i, i); // Run-Time }
int[] scores;
scores = new int[3];
scores[0] = 5;
Student[] cs149;
cs149 = new Student[3];
cs149[0] = new Student("Barney","Rubble");