If the contents of an object cannot be changed once the object is created, the object is called an
immutable object
and its class is called an
immutable class
. If you delete the
set
method in the
Circle3
class in the
A class with all private data fields and no mutators is not
public class Student { private int id; private BirthDate birthDate; public Student( int ssn, int year, int month, int day) { id = ssn; birthDate = new BirthDate(year, month, day); } public int getId() { return id; } public BirthDate getBirthDate() { return birthDate; } } public class BirthDate { private int year; private int month; private int day; public BirthDate( int newYear, int newMonth, int newDay) { year = newYear; month = newMonth; day = newDay; } public void setYear( int newYear) { year = newYear; } }
As shown in the following code, the data field birthDate is returned using the getBirthDate() method. This is a reference to a BirthDate object. Through this reference, the year of the birth date is changed, which effectively changes the contents of the Student object.
public class Test { public static void main(String[] args) { Student student = new Student( 111223333 , 1970 , 5 , 3 ); BirthDate date = student.getBirthDate(); date.setYear( 2010 ); //Now the student birth year is changed! } }
For a class to be immutable, it must mark all data fields private and provide no mutator
So far, you have learned how to pass arguments of primitive types and array types to methods. You can also pass objects to methods. Like passing an array, passing an object is actually passing the reference of the object. The following code
public class TestPassObject { public static void main(String[] args) { Circle3 myCircle = new Circle3( 5.0 ); printCircle(myCircle); } public static void printCircle(Circle3 c) { System.out.println( "The area of the circle of radius " + c.getRadius() + " is " + c.getArea()); } }
Java uses exactly one mode of passing arguments:
pass-
Let us
1 public class TestPassObject { 2 /** Main method */ 3 public static void main(String[] args) { 4 // Create a Circle object with radius 1 5 Circle3 myCircle = new Circle3(1); 6 7 // Print areas for radius 1, 2, 3, 4, and 5. 8 int n = 5 ; 9 printAreas(myCircle, n); 10 11 // See myCircle.radius and times 12 System.out.println( "\n" + "Radius is " + myCircle.getRadius()); 13 System.out.println( "n is " + n); 14 } 15 16 /** Print a table of areas for radius */ 17 public static void printAreas(Circle3 c, int times) { 18 System.out.println( "Radius \t\tArea" ); 19 while (times >= 1 ) { 20 System.out.println(c.getRadius() + "\t\t" + c.getArea()); 21 c.setRadius(c.getRadius() + 1 ); 22 times ” ”; 23 } 24 } 25 } |
The program passes a Circle3 object myCircle and an integer value from n to invoke printAreas(myCircle, n) (line 19), which prints a table of areas for radii 1 , 2 , 3 , 4 , and 5 , as shown in Figure 7.16.
Figure 7.17 shows the call stack for executing the methods in the program. Note that the objects are stored in a heap.
When passing an argument of a primitive data type, the value of the argument is passed. In this case, the value of n ( 5 ) is passed to times . Inside the printAreas method, the content of times is changed; this does not affect the content of n . When passing an argument of a reference type, the reference of the object is passed. In this case, c contains a reference for the object that is also referenced via myCircle . Therefore, changing the properties of the object through c inside the printAreas method has the same effect as doing so outside the method through the variable myCircle .