• No results found

static fields and methods

objects and classes

16 { 17 month = theMonth;

41 private int year;

3.6 additional constructs

3.6.5 static fields and methods

A static method is a method that does not need a control- ling object.

A static method is a method that does not need a controlling object, and thus is typically called by supplying a class name instead of the controlling object. The most common static method is main. Other static methods are found in the

Integer and Math classes. Examples are the methods Integer.parseInt,

Math.sin, and Math.max. Access to a static method uses the same visibility rules as do static fields. These methods mimic global functions found in non-object-oriented languages.

Static fields are

essentially global variables with class scope.

Static fields are used when we have a variable that all the members of

some class need to share. Typically, this is a symbolic constant, but it need not be. When a class variable is declared static, only one instance of the variable is ever created. It is not part of any instance of the class. Instead, it behaves like a single global variable but with the scope of the class. In other words, in the declaration

public class Sample {

private int x; private static int y; }

eachSample object stores its own x, but there is only one shared y.

A common use of a static field is as a constant. For instance, the class

Integer defines the field MAX_VALUE as

public static final int MAX_VALUE = 2147483647;

If this constant was not a static field, then each instance of an Integer would have a data field named MAX_VALUE, thus wasting space and initialization time. Instead, there is only a single variable named MAX_VALUE. It can be accessed by any of the Integermethods by using the identifier MAX_VALUE. It can also be accessed via an Integerobjectobjusingobj.MAX_VALUE, as would any field. Note that this is allowed only because MAX_VALUE is public. Finally,

MAX_VALUE can be accessed by using the class name as Integer.MAX_VALUE

field. The last form is preferable, because it communicates to the reader that the field is indeed a static field. Another example of a static field is the con- stantMath.PI.

Even without the final qualifier, static fields are still useful. Figure 3.9 illustrates a typical example. Here we want to construct Ticket objects, giving each ticket a unique serial number. In order to do this, we have to have some way of keeping track of all the previously used serial numbers; this is clearly shared data, and not part of any one Ticket object.

A static field is shared by all (possibly zero) instances of the class.

EachTicket object will have its instance member serialNumber; this is instance data because each instance of Tickethas its own serialNumberfield. All Ticket objects will share the variable ticketCount, which denotes the number of Ticketobjects that have been created. This variable is part of the class, rather than object-specific, so it is declared static. There is only one ticketCount, whether there is 1 Ticket, 10 Tickets, or even no Ticket

objects. The last point—that the static data exists even before any instances of the class are created—is important, because it means the static data cannot be initialized in constructors. One way of doing the initializa- tion is inline, when the field is declared. More complex initialization is described in Section 3.6.6.

In Figure 3.9, we can now see that construction of Ticket objects is done by using ticketCountas the serial number, and incrementing ticketCount. We also provide a static method, getTicketCount, that returns the number of tick- ets. Because it is static, it can be invoked without providing an object refer- ence, as shown on lines 36 and 41. The call on line 41 could have been made using either t1ort2, though many argue that invoking a static method using an object reference is poor style, and we would never do so in this text. How- ever, it is significant that the call on line 36 clearly could not be made through an object reference, since at this point there are no valid Ticketobjects. This is why it is important for getTicketCountto be declared as a static method; if it was declared as an instance method, it could only be called through an object reference.

Astatic method has no implicit thisreference, and can be invoked without an object reference.

When a method is declared as a static method, there is no implicit thisref- erence. As such, it cannot access instance data or call instance methods, without providing an object reference. In other words, from inside getTicketCount, unqualified access of serialNumber would imply this.serialNumber, but since there is no this, the compiler will issue an error message. Thus, a nonstatic field, which is part of each instance of the class, can be accessed by a static class method only if a controlling object is provided.

figure 3.9

TheTicket class: an example of static fields and methods

1 class Ticket

2 {