THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

2.5. Construction and Initialization


A newly created object is given an initial state. Fields can be initialized with a value when they are declared,
or you can accept their default value, which is sometimes sufficient to ensure a correct initial state. But often
you need more than simple initialization to create the initial state. For example, the creating code may need to
supply initial data or perform operations that cannot be expressed as simple assignment.


2.5.1. Constructors


For purposes other than simple initialization, classes can have constructors. Constructors are blocks of
statements that can be used to initialize an object before the reference to the object is returned by new.
Constructors have the same name as the class they initialize. Like methods, they take zero or more arguments,
but constructors are not methods and thus have no return type. Arguments, if any, are provided between the
parentheses that follow the type name when the object is created with new. Constructors are invoked after the
instance variables of a newly created object of the class have been assigned their default initial values and
after their explicit initializers are executed.


This improved version of the Body class uses both constructors and initializers to set up each new object's
initial state:


class Body {
public long idNum;
public String name = "";
public Body orbits = null;
private static long nextID = 0;


Body() {
idNum = nextID++;
}
}


A constructor declaration consists of the class name followed by a (possibly empty) list of parameters within
parentheses and a body of statements enclosed in curly braces. Constructors can have any of the same access
modifiers as class members, but constructors are not members of a classa distinction you can usually ignore,
except when it comes to inheritance. Constructors can also have annotations applied to them; see Chapter 15.


The constructor for Body takes no arguments, but it performs an important functionassigning a proper
idNum to the newly created object. In the original code, a simple programmer errorforgetting to assign the
idNum or not incrementing nextID after usecould result in different Body objects with the same idNum.
That would create bugs in code that relies on the part of the contract that says "All idNum values are
different."


By moving responsibility for idNum generation inside the Body class, we have prevented errors of this kind.
The Body constructor is now the only entity that assigns idNum and is therefore the only entity that needs
access to nextID. We can and should make nextID private so that only the Body class can access it. By
doing so, we remove a source of error for programmers using the Body class.


We also are now free to change the way idNum values are assigned to Body objects. A future
implementation of this class might, for example, look up the name in a database of known astronomical
entities and assign a new idNum only if an idNum had not previously been assigned. This change would not
affect any existing code, because existing code is not involved at all in the mechanism for idNum allocation.

Free download pdf