Class Variables


You will occasionally want to track information about all instances of a class or perform an operation without first creating an instance of an object. As a simplistic example, you might want to track the total number of course sessions. As each CourseSession object is created, you want to bump up a counter. The question is, where should you put this counter? You could provide an instance variable on CourseSession to track the count, but this is awkward: Would all instances of CourseSession have to track the count? How would one CourseSession instance know when others were created so that it could update the count?

You could provide another class, CourseSessionCounter, whose sole responsibility is to track the CourseSession objects created. But a new class seems like overkill for the simple goal you are trying to accomplish.

In Java, you can use class variables, as opposed to instance variables, for a solution. Client code can access a class variable without first creating an instance of that class. Class variables have what is known as static scope: they exist as long as the class exists, which is pretty much from the time the class is first loaded until your application terminates.

You have already seen class constants in use. Class constants are class variables that you have designated as final.

The following test code (in CourseSessionTest) counts the number of CourseSession instances created:

 public void testCount() {    CourseSession.count = 0;    createCourseSession();    assertEquals(1, CourseSession.count);    createCourseSession();    assertEquals(2, CourseSession.count); } private CourseSession createCourseSession() {    return new CourseSession("ENGL", "101", startDate); } 

(Don't forget to update the setUp method to use createCourseSession.)

To support the test, create a class variable in the CourseSession class named count. You use the static keyword to designate a variable as static in scope. Also add code to CourseSession to update count when a new Course-Session instance is created.

 public class CourseSession {    // ... static int count;    public CourseSession(          String department, String number, Date startDate) {       this.department = department;       this.number = number;       this.startDate = startDate;       CourseSession.count = CourseSession.count + 1;    }    // ... 

You access the class variable count similar to the way you call a class method: First specify the class name (CourseSession), followed by the dot (.) operator, followed by the variable name (count). The Java VM does not create an instance of CourseSession when code accesses the class variable.

As I mentioned, class variables have a different lifetime than instance variables. Instance variables stick around for the lifetime of the object that contains them. Each new CourseSession object that the Java VM creates manages its own set of the instance variables declared in CourseSession. When the VM creates a CourseSession object, it initializes its instance variables.

A class variable, however, comes into existence when the Java VM first loads the containing classwhen code that is currently executing first references the class. There is one copy of the class variable in memory. The first time the Java VM loads a class, it initializes its class variables, and that's it. If you need to reset a class variable to an initial state at a later time, you must explicitly initialize it yourself.

As an experiment, comment out the first line in testCount (the line that reads CourseSession.count = 0). Then run the tests in JUnit. Turn off the checkbox in JUnit that says "Reload classes every run."[2] If you run the tests twice (by clicking the Run button), they will fail, and you should see the actual count go up with each execution of the tests. You may even see the first run of the test fail: Other test methods in CourseSessionTest are creating CourseSession objects, which increments the count variable.

[2] This JUnit switch, when turned on, results in your test classes being physically loaded from disk and reinitialized each time the tests are run in JUnit. If you are running in an IDE such as Eclipse, you may not have control over this JUnit feature.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

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