Static Nested Classes and Inner Classes


DataFileTest needs to show that DataFile can persist an object and retrieve that object at a later time. In order to write such a test, it's best to use a class that you can guarantee no one else will change. You could use a Java system library class such as String, but they change with new releases of Java. Instead, the better solution is to create a test class solely for use by DataFileTest.

The class TestData is defined as a nested class of DataFileTest; that is, it is completely contained within DataFileTest. There are two kinds of nested classes: inner classes and static nested classes. The chief distinction is that inner classes have access to the instance variables defined within the enclosing class. Static nested classes do not.

Another distinction is that inner classes are completely encapsulated by the enclosing class. Since inner classes can refer to instance variables of the enclosing class, it makes no sense for other code to be able to create instances of an instance inner class. While Java technically allows you to refer to aninner class from external code, it's a bit of trickery that I'm not going to show you heredon't do it!

Class Names for Nested Classes

When you compile a class or interface, the compilation unit is named by taking the class name and appending a .class file extension. For example, the Course class compiles to Course.class.

When compiling a class containing a nested class, Java names the compilation unit for the inner class by first using the containing class name, followed by the dollar sign ($),then the nested class name.

For example, the DataFileTest class creates two compilation units: DataFileTest.class and DataFileTest$TestData.class.

When you copy class files or put them in a JAR file (see Additional Lesson III) for distribution, don't forget to include all the nested classes.


Static nested classes, on the other hand, can be used by external code as long as the access specifier is not private. You have already used the static nested class Entry in order to iterate key-value pairs in a Map object. You referred to this class as Map.Entry, since you used it in a code context other than Map.

So the first reason to declare a nested class as static is to allow other classes to use it. You could declare the class as a top-level (i.e., non-nested) class, but you may want to tightly couple it to the containing class. For example, Map.Entry is tightly bound to Map, since it makes no sense for the Entry class to exist in the absence of Map.

The second reason to declare a nested class as static is to allow it to be serialized. You cannot serialize inner class objects, since they must have access to the instance variables of the enclosing class. In order to make it work, the serialization mechanism would have to capture the fields of the enclosing class. Yuck.

Since you need to persist TestData objects, you must make the class serializable. If TestData is to be a nested class, you must declare it as static.



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