Summary


Special Topics

Before bringing this chapter to a close I’d like to talk briefly about static initializers and data encapsulation.

Static Initializers

When classes contain static fields (a.k.a. class fields) they must be initialized before any instance of the class is created. If you initialized the static field in the constructor then each time a new object is created the static field’s value would be overwritten. This is generally not the desired behavior.

If the static field just needs to be initialized to a simple value then its declaration within the class and same-line initialization will suffice. However, if you have to perform a non-trivial initialization, like the initialization of an array, then you can use a static initializer to perform the initialization. The code in example 9.19 offers an example of a static initializer in action. Figure 9-13 shows the results of running this program.

Example 9.19: StaticInitializerTest.java

image from book
 1     public class StaticInitializerTest { 2        private static int static_int_val; 3        private static int[] static_int_array = new int[10]; 4        static { 5               for(int i = 0; i < static_int_array.length; i++){ 6                   static_int_array[i] = i; 7               } 8        }//end static class initializer 9 10       /****** Constructor Method ********/ 11        public StaticInitializerTest(){ 12            static_int_val++; 13        } 14 15       /***** printStaticArrayValues method ******/ 16       public void printStaticArrayValues(){ 17         for(int i = 0; i < static_int_array.length; i++){ 18          System.out.print(static_int_array[i] + " "); 19         } 20         System.out.println(); 21       } 22 23       /****** getStaticIntVal method ******/ 24       public int getStaticIntVal(){ return static_int_val; } 25 26       /***** main method ********/ 27       public static void main(String[] args){ 28        StaticInitializerTest sit1 = new StaticInitializerTest(); 29        System.out.println(sit1.getStaticIntVal()); 30 31        StaticInitializerTest sit2 = new StaticInitializerTest(); 32        System.out.println(sit2.getStaticIntVal()); 33 34        StaticInitializerTest sit3 = new StaticInitializerTest(); 35        System.out.println(sit3.getStaticIntVal()); 36 37        StaticInitializerTest sit4 = new StaticInitializerTest(); 38        System.out.println(sit4.getStaticIntVal()); 39 40        sit1.printStaticArrayValues(); 41        sit2.printStaticArrayValues(); 42        sit3.printStaticArrayValues(); 43        sit4.printStaticArrayValues(); 44       } //end main 45      } //end class
image from book

image from book
Figure 9-13: Results of Running Example 9.19

Referring to example 9.19 — Two static fields are declared for the StaticInitializerTest class. The static_int_val field is just a simple field and it is automatically initialized to zero when the class is loaded into the Java virtual machine. The static_int_array is a special case. When it is created on line three all the elements will be initialized to zero which is what you expect. However, if you did not want all the elements to remain at zero then you have two options: 1) use array literals to initialize the array (see chapter 8) or, 2) use the static initializer as is shown on line 4.

A static initializer is simply a block of code preceded by the keyword static. There can be more than one static initializer and they can appear anywhere within the class definition that a field or method declaration can appear, but, if they are used at all, their is usually just one and it is placed just above the first constructor method for clarity.

Static initializers behave like static methods in that they cannot use the this keyword and cannot reference instance variables or methods.

Data Encapsulation - The Naked Truth

You were introduced to data encapsulation early in the chapter when talking about private instance fields. I then proceeded to show you how to write getter and setter methods that manipulate a few of the private fields of the Person class. Getter methods, if used improperly, can violate your best efforts at encapsulation. In the case of the Person class, the use of getter methods to return a reference to the fields first_name, middle_name, and last_name was not necessarily a bad thing. This is because String objects are immutable. That is, Strings cannot be changed once created. Any String method such as toUpperCase() or toLowerCase() that appears to modify the String object actually returns a new String object. The immutable nature of Strings prevents a Person object’s String fields from being modified even if a reference to them is returned.

If, however, a class contains fields of mutable (changeable) types then you must not return references to those fields willy-nilly. The requirements of your design will dictate how you enforce data encapsulation.

The idea behind data encapsulation is simply the separation of what a class can do from how it actually does it. If you mindlessly expose the innards of a class to the outside world you will have difficulty in the future should you decide to change the class’s innards.

Quick Review

Static initializers can be used to perform complex initialization of static class fields. There can be more than one static initializer in a class and they can appear anywhere a field or method declaration appears.

Data encapsulation can be unwittingly violated through the improper use of getter and setter methods. Let good class design be your guide in choosing exactly what, if any, internal pieces of a class to expose.




Java For Artists(c) The Art, Philosophy, and Science of Object-Oriented Programming
Java For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504052
EAN: 2147483647
Year: 2007
Pages: 452

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