HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

Often it-s very useful to create classes that represent a restricted number of real-world entities in our Java programs. For example, there is only a single instance of the java.awt.Toolkit class that ever exists in a single Java VM. This Toolkit represents the windowing system on the local machine. It would generally not make sense to have more than one Toolkit object, so the Toolkit class is designed to ensure that only one instance can ever be created. The Toolkit class is an example of what is termed a Singleton class.

Java classes have the interesting capability to represent singleton resources themselves. That is, you could use a static-only class to represent a single resource. The best example that comes to mind in Java-s Core API is the System class. The System class represents the O/S information and functionality available to your Java application: system properties, loading dynamically loadable libraries, access to the VM-s garbage collector, etc.

Singletons are a specific example of a more general concept: the N-ton class. The N-ton class is a class in which only N objects are created; N being a finite number. (A singleton class is an N-ton class where N equals one.) An example of an N-ton class would be a class to represent the serial ports available on a given machine. On a given machine there are a finite number of serial ports which you can use to communicate with serial devices, like modems, Iomage Zip drives, etc. It is easy to imagine a Java class that represents the serial ports available. You would want to design this class so that only a finite number of objects of that type would be created.

In this month-s column I-m going to discuss the features of N-ton classes verses static-only classes and talk about when it is appropriate to use either approach.

Starting with Static-Only Classes
The primary feature of a static-only class is that, like the term implies, all of the members of the class are declared as "static". There are no instance variables or instance members for the class. Instead, the state of the resource being represented is stored in static variables of the static-only class. The functionality of the resource is exposed through the static methods of the static-only class. Using the example of the java.lang.System class, the system-s "state" is represented using the static variables of the System class. The variables "in", "out" and "err", for example, are used to access the standard input, output and error streams of the current process, respectively. All three of these variables are declared as static.

The point of a static-only class is that you never actually create an object of that type. Instead you use the static members of the class very much like you would a singleton object. It is easy to ensure that an object of a static-only class is never created. You have two options available to do this (or you could use both, although that-s overkill):

  1. Declare the class constructor as "private". This ensures that no code external to your class can create any objects of that type; the compiler simply won-t let you. However, this does not restrict code within the static-only class from creating a new instance. That-s why I prefer the second option.
  2. Declare the static-only class as "abstract". No code, even code within the static-only class itself, can create an object of an abstract type. So, adding the "abstract" attribute to your class guarantees no instance will ever be created.
Static-only classes are not used in other popular object-oriented languages mainly for one reason: How do you initialize static variables? That is, static variables are, by default, initialized to zero-states (numbers and chars are zero, booleans are false and object references are null). In languages like C++ there-s no easy way to initialize the static variables of a class without writing and calling special methods to do so.

The Java language provides us with the "static initializer block" which allows you to initialize static variables in a class when the class is loaded into the VM. So, if I was writing Java-s java.lang.System class, I would add a static initializer block in the class to set the "in", "out" and "err" static variables to non-null object references. When the System class is loaded, the static initializer is automatically run, which would guarantee my static variables would never be null. Listing 1 shows an excerpt of the System class I would write. The static initializer block is the block of code preceded solely by the keyword "static".

N-ton Classes
N-ton classes, including singleton classes, are a bit different than the static-only classes. The idea of an N-ton class is that you do create instances of the class, but you want to guarantee only a finite number are ever made. So the features of an N-ton class are a little different than static-only classes. N-ton classes usually have private constructors (or, in some cases, package-private or protected, but for simplicity I-ll stick to "private"). You get a reference to one of the N class instances through one of two different mechanisms. The first is a static "lookup" method; a method that takes some sort of identifier (a String or ID number, for example) as a parameter and returns an instance for that identifier. This is the way to do it if you don-t necessarily know the number of objects at compile time. For example, the serial port class I mentioned earlier might have a lookup method with this signature:

// static Lookup method for a SerialPort class
public static getPort(int portNumber) {...}

The second mechanism for obtaining a reference to an N-ton object is through a set of N static object reference variables of the class type. This would be the way to do it if you know the number of objects at compile time. These N static variables could be initialized using a static initializer block the same way a static-only class would use to initialize its static variables. Listing 2 shows example code for this kind of N-ton class.

An example in the Java Core API of an N-ton class is the java.net.InetAddress class. For this class, N is huge (the number of host machines on the Internet, which numbers in the millions), but it is finite. The InetAddress class has both features I-ve listed for N-ton classes: a restricted constructor and a public static "lookup" method.

An N-ton setup is clearly the way to go if N is greater than one. Which begs the question: "Should I use a static-only class or an N-ton class when N is equal to one (i.e., for a singleton class)?". The answer, just as clearly, is: "It depends." Either technique would work, in theory. But one attribute makes it easy to differentiate which technique you should use for singleton classes. That attribute I call "replaceability".

Replaceability is the ability to replace a singleton-s implementation at runtime. The java.awt.Toolkit class is a great example of a singleton with a replaceable implementation. The Toolkit class itself is an abstract class. The idea is that different VM implementors will provide a different (that is, replacement) implementation for the Toolkit on different systems. Microsoft provides a Toolkit-derived class to be used with their VMs on MS systems, and Sun provides their own Toolkit-derived class to be used in their VMs. The Toolkit implementation needs to be replaced with a particular implementation on different systems.

In cases where replaceability is required, it is most appropriate to use the N-ton class design and less appropriate to use the static-only design. The Toolkit class itself has both of the features I listed above for N-ton classes: a restricted constructor and a static lookup method (called Toolkit.getDefaultToolkit). In Listing 3 I show my implementation of the getDefaultToolkit method of the Toolkit class. This method finds the correct implementation of Toolkit functionality to use on the current system by looking for the system property "java.awt.toolkit" and using its value as the name of the replaceable implementation.

The System class, on the other hand, is a static-only class to represent a singleton resource. In this case, replaceablity is not a concern so a static-only implementation is used. The System class itself has the features listed above for static-only classes; a private constructor and the class public interface includes only static members and methods.

There-s one other major difference between the static-only design and the N-ton design. That difference is that N-ton object instances are finalized, which allows you to clean up allocated resources. Static-only classes, on the other hand, generally never experience finalization and so have no opportunity for class clean up. In next month-s column I-ll discuss object and class finalization, which should help explain this key difference more clearly. I-ll also show how to approximate static "uninitializer" blocks in your Java classes.

About the Author
Brian Maso is a Java programming consultant and president of Blumenfeld & Maso, Inc. He works out of Dana Point, CA. He is the author of several Java books. Before Java, he spent five years corralled in the MS Windows branch of programming, working for such notables as the Hearst Corp., First DataBank, and Intel. Readers are encouraged to contact Brian via e-mail with any comments or questions at [email protected]

	

Listing 1: My implementation of part of the java.lang.System class.
  
//Note use of static member variables, a private constructor and a 
//static initializer block.  
//NOTE: This not how the Java Core API source code implements //this class. 
This is to demonstrate using a public static   
//interface to make a static-only class.  

package java.lang;  

import java.io.*;  

public class System {  
  public final static InputStream in = getIn();  
  public final static PrintStream out = getOut();  
  public final static PrintStream err = getErr();  

  static {  
    // Load native implementation of getXYZ() methods  
    loadLibrary("System");  
  }  

  private static native InputStream getIn();  
  private static native InputStream getOut();  
  private static native InputStream getErr();  

  private System() { }  

  ...  
}  

Listing 2: Implementation of an N-ton class.
  
//Features include restricted constructor, finite number of public 
//static objects representing the N objects, static initializer 
//block initializing the objects.  
public class Color {  
  int red, green, blue;  

  private Color(int r, int g, int b) {  
    red = r;  
    green = g;  
    blue = b;  
  }  

  public static Color Red;  
  public static Color Green;  
  public static Color Blue;  
  public static Color Purple;  
  public static Color Orange;  
  ...  

  static {  
    Red = new Color(255, 0, 0);  
    Green = new Color(0, 255, 0);  
    Blue = new Color(0, 0, 255);  
    ...  
  }  
}  

Listing 3: Part of the Toolkit class. Uses N-ton pattern to support replaceablity.
  
package java.awt;  

public abstract class Toolkit {  
  ...  

  private static Toolkit theToolkit;  

  static {  
    try {  
      String toolkitClassName =  
          System.getProperty("java.awt.toolkit");  
      Class clsToolkit = Class.forName(toolkitClassName);  
      theToolkit = clsToolkit.newInstance();  
    } catch (Exception e) {  
      theToolkit = null;  
    }  
  }  

  public static Toolkit getDefaultToolkit() {  
    if(theToolkit == null)  
      throw new RuntimeException("No toolkit exists!");  

    return theToolkit;  
  }  

 
  
      
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.