Java Tip 106: Static inner classes for fun and profit

Use static inner classes to add supplementary capabilities to your code

With this tip, you can add the use of static inner classes to your bag of Java tricks. A static inner class is a class that is defined inside of a different class's definition and marked as being static. I'll show you an example of using static inner classes to add testing code to a class.

Static inner classes are pretty simple in concept and implementation. Basically, you define a static class inside your primary class:

public class Foo
    {
    // ....
    public static class Test
      {
      public static void main (String[] args)
          {
          // ....
          }
      }
    }

In terms of adding supplementary code to your primary class, the key point is that a static inner class is compiled into a completely separate .class file from the outer class. For example, if the outer class is named Foo, then an inner class of Foo, which is named Test, would be compiled into Foo$Test.class. The separation of .class files means that you can keep the supplemental, nested code tightly coupled to the primary, outer class. They are in the same source file, and the inner class is actually inside the outer class. All that and you don't have to pay any sort of deployment or runtime cost. Score! For example, if the supplemental code is only used for, say, debugging, then you only have to ship the Foo.class file and leave the Foo$Test.class file at home.

I primarily use that trick for writing example code to show how to use the primary outer class, for writing down and dirty debugging code, and for writing unit tests to automate the validation of the class's behavior. (Of course, being a diligent developer, I tend to transform the debugging code into unit tests.)

Note that to execute the main() method of that Foo.Test class, you use:

      % java Foo$Test

If you're using a command shell that uses "$" as a metacharacter, you would instead use:

      % java Foo\$Test

Another interesting point to note is that static inner classes have, by definition, access to the outer class's protected and private fields. That is both a blessing and a curse since you can, in essence, violate the encapsulation of the outer class by mucking up the outer class's protected and private fields. Tread with care! The only proper use of that capability is to write white-box tests of the class -- since I can induce cases that might be very hard to induce via normal black-box tests (which don't have access to the internal state of the object).

The XYPair class is quite simple. It just provides for an immutable pair of integers, (x, y). The XYPair.Test class has a main() method that drives a simple test of the XYPair and prints the results. Play with both the testing and core code to experiment with various problems.

If you're more bold, you might want to check out the JUnit Java unit testing framework. You can uncomment out the various spots indicated in the source code and then run the tests via JUnit's test engine.

Conclusion

By using static inner classes, you can add additional support functionality to your systems for capabilities such as testing, while incurring no penalties in normal, production deployment.

John Mitchell works as an independent consultant, investing the last 13 years in developing cutting-edge computer software and advising developers and investors. John coauthored Making Sense of Java: A Guide for Managers and the Rest of Us (Manning, 1996), and he has published various articles in programming journals. In addition to writing JavaWorld's Java Tips 'N Tricks column, he moderates the comp.lang.tcl.announce and comp.binaries.geos newsgroups. For more about John, go to JGuru.com.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies