25. Java Inner Classes

25.3. Local and Anonymous Inner Classes

In this next example, ConverterFrame, a local class is used to create an

ActionEvent handler for the application’s two buttons (Fig. F–2).

As we have seen, Java’s event-handling model uses predefined interfaces, such as the ActionListener interface, to handle events. When a separate class is defined to implement an interface, it is sometimes called an adapter class. Rather than defining adapter classes as top-level classes, it is often more convenient to define them as local or anonymous classes.

The key feature of the ConverterFrame program is the createJButton() method. This method is used instead of the JButton() constructor to create but- tons and to create action listeners for the buttons. It takes a single String param- eter for the button’s label. It begins by instantiating a new JButton, a reference to which is passed back as the method’s return value. After creating an instance button, a local inner class named ButtonListener is defined.

The local class merely implements the ActionListener interface by defining the actionPerformed method. Note how actionPerformed() uses the con- taining class’s converter variable to acquire access to the metersToInches() and kgsToPounds() methods, which are inner class methods of the Converter class (Fig. F–1). A local class can use instance variables, such as converter, that are defined in its containing class.

 

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

J

Figure F–2: The use of a local class as an ActionListener adapter.

 

 

After defining the local inner class, the createJButton() method creates an instance of the class (listener) and registers it as the button’s action listener. When a separate object is created to serve as listener in this way, it is called an adapter. It implements a listener interface and thereby serves as adapter between

 

the event and the object that generated the event. Any action events that occur on any buttons created with this method will be handled by this adapter. In other words, for any buttons created by the createJButton() method, a listener ob- ject is created and assigned as the button’s event listener. By using local classes, the code for doing this is much more compact and efficient.

Local classes have some important restrictions. Although an instance of a local class can use fields and methods defined within the class itself or inherited from its superclasses, it cannot use local variables and parameters defined within its scope unless these are declared final. The reason for this restriction is that final vari- ables receive special handling by the Java compiler. Because the compiler knows that the variable’s value won’t change, it can replace uses of the variable with their values at compile time.

 

Anonymous Inner Classes

An anonymous inner class is just a local class without a name. Instead of using two separate statements to define and instantiate the local class, Java provides syntax that let’s you do it in one expression. The following code illustrates how this is done:

,,

 

 

 

 

 

 

 

 

 

 

J

Note that the body of the class definition is put right after the new operator. The result is that we still create an instance of the adapter object, but we define it on the fly. If the name following new is a class name, Java will define the anonymous class as a subclass of the named class. If the name following new is an interface, the anonymous class will implement the interface. In this example, the anonymous class is an implementation of the ActionListener interface.

Local and anonymous classes provide an elegant and convenient way to im- plement adapter classes that are intended to be used once and have relatively short and simple implementations. The choice of local versus anonymous should largely depend on whether you need more than one instance of the class. If so, or if it’s important that the class have a name for some other reason (readability), then you should use a local class. Otherwise, use an anonymous class. As in all design decisions of this nature, you should use whichever approach or style makes your code more readable and more understandable.

 

 

 

 

 

 

 

 

 

Appendix G