static Class Members

Every object has its own copy of all the instance variables of the class. In certain cases, only one copy of a particular variable should be shared by all objects of a class. A static fieldcalled a class variableis used in such cases. A static variable represents classwide informationall objects of the class share the same piece of data. The declaration of a static variable begins with the keyword static.

Let's motivate static data with an example. Suppose that we have a video game with Martians and other space creatures. Martians tend to be brave and willing to attack other space creatures when the Martian is aware that there are at least four other Martians present. If fewer than five Martians are present, become cowardly. Thus each Martian needs to know the martianCount. We could endow class Martian with martianCount as an instance variable. If we do this, then every Martian will have a separate copy of the instance variable, and every time we create a new Martian, we will have to update the instance variable martianCount in every Martian. This wastes space with the redundant copies, wastes time in updating the separate copies and is error prone. Instead, we declare martianCount to be static, making martianCount classwide data. Every Martian can see the martianCount as if it were an instance variable of class Martian, but only one copy of the static martianCount is maintained. This saves space. We save time by having the Martian constructor increment the static martianCountthere is only one copy, so we do not have to increment separate copies of martianCount for each Martian object.

Software Engineering Observation 8.11

Use a static variable when all objects of a class must use the same copy of the variable.

Static variables have class scope. A class's public static members can be accessed through a reference to any object of the class, or they can be accessed by qualifying the member name with the class name and a dot (.), as in Math.random(). A class's private static class members can be accessed only through methods of the class. Actually, static class members exist even when no objects of the class existthey are available as soon as the class is loaded into memory at execution time. To access a public static member when no objects of the class exist (and even when they do), prefix the class name and a dot (.) to the static member, as in Math.PI. To access a private static member when no objects of the class exist, a public static method must be provided and the method must be called by qualifying its name with the class name and a dot.

Software Engineering Observation 8.12

Static class variables and methods exist, and can be used, even if no objects of that class have been instantiated.

Our next program declares two classesEmployee (Fig. 8.12) and EmployeeTest (Fig. 8.13). Class Employee declares private static variable count (Fig. 8.12, line 9), and public static method getCount (lines 4649). The static variable count is initialized to zero in line 9. If a static variable is not initialized, the compiler assigns a default value to the variablein this case 0, the default value for type int. Variable count maintains a count of the number of objects of class Employee that currently reside in memory. This includes objects that have already been marked for garbage collection by the JVM, but have not yet been reclaimed by the garbage collector.

Figure 8.12. static variable used to maintain a count of the number of Employee objects in memory.

(This item is displayed on pages 381 - 382 in the print version)

 1 // Fig. 8.12: Employee.java
 2 // Static variable used to maintain a count of the number of
 3 // Employee objects in memory.
 4
 5 public class Employee
 6 {
 7 private String firstName;
 8 private String lastName;
 9 private static int count = 0; // number of objects in memory
10
11 // initialize employee, add 1 to static count and
12 // output String indicating that constructor was called
13 public Employee( String first, String last )
14 {
15 firstName = first;
16 lastName = last;
17
18 count++; // increment static count of employees
19 System.out.printf( "Employee constructor: %s %s; count = %d
",
20 firstName, lastName, count );
21 } // end Employee constructor
22
23 // subtract 1 from static count when garbage
24 // collector calls finalize to clean up object;
25 // confirm that finalize was called
26 protected void finalize()
27 {
28 count--; // decrement static count of employees
29 System.out.printf( "Employee finalizer: %s %s; count = %d
",
30 firstName, lastName, count );
31 } // end method finalize
32
33 // get first name
34 public String getFirstName()
35 {
36 return firstName;
37 } // end method getFirstName
38
39 // get last name
40 public String getLastName()
41 {
42 return lastName;
43 } // end method getLastName
44
45 // static method to get static count value
46 public static int getCount() 
47 { 
48  return count; 
49 } // end method getCount 
50 } // end class Employee

Figure 8.13. static member demonstration.

(This item is displayed on pages 382 - 383 in the print version)

 1 // Fig. 8.13: EmployeeTest.java
 2 // Static member demonstration.
 3
 4 public class EmployeeTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 // show that count is 0 before creating Employees
 9 System.out.printf( "Employees before instantiation: %d
",
10 Employee.getCount() );
11
12 // create two Employees; count should be 2
13 Employee e1 = new Employee( "Susan", "Baker" );
14 Employee e2 = new Employee( "Bob", "Blue" ); 
15
16 // show that count is 2 after creating two Employees
17 System.out.println( "
Employees after instantiation: " );
18 System.out.printf( "via e1.getCount(): %d
", e1.getCount() );
19 System.out.printf( "via e2.getCount(): %d
", e1.getCount() );
20 System.out.printf( "via Employee.getCount(): %d
",
21 Employee.getCount() );
22
23 // get names of Employees
24 System.out.printf( "
Employee 1: %s %s
Employee 2: %s %s

",
25 e1.getFirstName(), e1.getLastName(),
26 e2.getFirstName(), e2.getLastName() );
27
28 // in this example, there is only one reference to each Employee,
29 // so the following two statements cause the JVM to mark each 
30 // Employee object for garbage collection 
31 e1 = null; 
32 e2 = null; 
33
34 System.gc(); // ask for garbage collection to occur now
35
36 // show Employee count after calling garbage collector; count
37 // displayed may be 0, 1 or 2 based on whether garbage collector
38 // executes immediately and number of Employee objects collected
39 System.out.printf( "
Employees after System.gc(): %d
",
40 Employee.getCount() );
41 } // end main
42 } // end class EmployeeTest
 
Employees before instantiation: 0
Employee constructor: Susan Baker; count = 1
Employee constructor: Bob Blue; count = 2

Employees after instantiation:
via e1.getCount(): 2
via e2.getCount(): 2
via Employee.getCount(): 2

Employee 1: Susan Baker
Employee 2: Bob Blue

Employee finalizer: Bob Blue; count = 1
Employee finalizer: Susan Baker; count = 0

Employees after System.gc(): 0
 

When Employee objects exist, member count can be used in any method of an Employee objectthis example increments count in the constructor (line 18) and decrements it in the finalize method (line 28). When no objects of class Employee exist, member count can still be referenced, but only through a call to public static method getCount (lines 4649), as in Employee.getCount(), which returns the number of Employee objects currently in memory. When objects exist, method getCount can also be called through any reference to an Employee object, as in the call e1.getCount().

Good Programming Practice 8.1

Invoke every static method by using the class name and a dot (.) to emphasize that the method being called is a static method.

Note that the Employee class has a finalize method (lines 2631). This method is included only to show when the garbage collector executes in this program. Method finalize is normally declared protected, so it is not part of the public services of a class. We will discuss the protected member access modifier in detail in Chapter 9.

EmployeeTest method main (Fig. 8.13) instantiates two Employee objects (lines 1314). When each Employee object's constructor is invoked, lines 1516 of Fig. 8.12 assign the Employee's first name and last name to instance variables firstName and lastName. Note that these two statements do not make copies of the original String arguments. Actually, String objects in Java are immutablethey cannot be modified after they are created. Therefore, it is safe to have many references to one String object. This is not normally the case for objects of most other classes in Java. If String objects are immutable, you might wonder why are we able to use operators + and += to concatenate String objects. String concatenation operations actually result in a new Strings object containing the concatenated values. The original String objects are not modified.

When main has finished using the two Employee objects, the references e1 and e2 are set to null at lines 3132. At this point, references e1 and e2 no longer refer to the objects that were instantiated on lines 1314. This "marks the objects for garbage collection" because there are no more references to the objects in the program.

Eventually, the garbage collector might reclaim the memory for these objects (or the operating system surely will reclaim the memory when the program terminates). The JVM does not guarantee when the garbage collector will execute (or even whether it will execute), so this program explicitly calls the garbage collector in line 34 using static method gc of class System (package java.lang) to indicate that the garbage collector should make a best-effort attempt to reclaim objects that are eligible for garbage collection. This is just a best effortit is possible that no objects or only a subset of the eligible objects will be collected. In Fig. 8.13's sample output, the garbage collector did execute before lines 3940 displayed current Employee count. The last output line indicates that the number of Employee objects in memory is 0 after the call to System.gc(). The third- and second-to-last lines of the output show that the Employee object for Bob Blue was finalized before the Employee object for Susan Baker. The output on your system may differ, because the garbage collector is not guaranteed to execute when System.gc() is called, nor is it guaranteed to collect objects in a specific order.

[Note: A method declared static cannot access non-static class members, because a static method can be called even when no objects of the class have been instantiated. For the same reason, the this reference cannot be used in a static methodthe this reference must refer to a specific object of the class, and when a static method is called, there might not be any objects of its class in memory. The this reference is required to allow a method of a class to access other non-static members of the same class.]

Common Programming Error 8.7

A compilation error occurs if a static method calls an instance (non-static) method in the same class by using only the method name. Similarly, a compilation error occurs if a static method attempts to access an instance variable in the same class by using only the variable name.

Common Programming Error 8.8

Referring to this in a static method is a syntax error.


Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net