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.