Return to index

 

Inner Classes & Anonymous Classes

 

Inner Classes

Inner classes provide a convenient way to define a class that is only required within the scope of the class that contains it. An example is the inner class WinAdapter that TJI uses in its default Application framework. The class is defined at the same indentation level as a method and can be instantiated from the class that contains it. However, if the inner class is not declared 'private', it can be referenced from other classes too; Paint.WinAdapter in the following example.

package projects.paint;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class Paint extends JFrame implements ActionListener {

private JPanel contentPane;
private PaintMenuBar menuBar;
private PaintToolBar toolBar;
private PaintStatusBar statusBar;
private PaintContentPanel contentPanel;

public Paint(){

WinAdapter winAdapter=new WinAdapter();
addWindowListener(winAdapter);

...

}

public void actionPerformed(ActionEvent e){ [...]
}

public static void main(String[] args){

new Paint();

}

class WinAdapter extends WindowAdapter {

public void windowClosing(WindowEvent e){

System.exit(0);

}

}

}

When compiled, a class file called Paint.WinAdapter.class will be created.

 

Anonymous Classes

An anonymous class is just what its name imples -- it has no name. It combines the class declaration and the creation of an instance of the class in one step.

When defining an anonymous class, the definition and object instantiation is done all in one step. The class itself has no name (hence 'anonymous') and the only instance is the one made at the point of definition. An anonymouse class may be used in an assignment or as a method call argument, as in the following example.

First, consider the straightforward case of adding an action listener to a button where the action listener is defined elsewhere (perhaps an inner class or a completely separate, top-level class):

ButtonListener myButtonListener=new ButtonListener();
myButton.addActionListener(myButtonListener);

Or, if we do not need to keep a reference to the listener and it is used with only button:

myButton.addActionListener(new ButtonListener());

We could define and instantiate ButtonListener in one step using an anonymous class:

int i = 0;
myButton.addActionListener(

new ActionListener() {

public void actionPerformed (ActionEvent e) {

i++;
System.out.println ("Button has been pressed "+i+" times.");

}

}

);

Anonymous classes are never essential but can be time-savers and reduce the number of Java files required to define an application. They should be used only for simple tasks with a specific and usually unique purpose. They are often used to implement listeners on GUI components. Even if you feel that complex statements are best avoided, it is still good to understand how they work, because you may see anonymous classes in the source code of others.

When you compile a class that contains an anonymous class, the compiler will create separate class files named ClassName$SomeNumber.class where ClassName is the name of the class in which this anonymous class is defined, and SomeNumber is a sequence number for the anonymous class.

As an exercise, you could try changing the application framework inner class so that it is used as an anonymous class.

 

Local Inner Class

An alternative to an anonymous class that is to define an inner class within a method - and then create and use an instance of it within the method. For example:

void setupButton() {

myButton=new JButton();

class MyListener extends ActionListener {

int i = 0;

public void actionPerformed(ActionEvent e) {

i++;
System.out.println("Button has been pressed "+i+" times.");

}

}

myButton.addActionListener(new MyListener());

}


Return to index