Skip to content Skip to navigation Skip to collection information

OpenStax_CNX

You are here: Home » Content » Object-Oriented Programming (OOP) with Java » Java OOP: Anonymous Classes

Navigation

Table of Contents

Recently Viewed

This feature requires Javascript to be enabled.
 

Java OOP: Anonymous Classes

Module by: R.G. (Dick) Baldwin. E-mail the author

Summary: Baldwin explains anonymous classes from a practical viewpoint, including a comparison between anonymous classes and local classes.

Preface

This module is one in a collection of modules designed for teaching ITSE2317 - Java Programming (Intermediate) at Austin Community College in Austin, TX.

(Editor's note: As you read this module, you will see that it was originally written around 2003. However, despite many improvements in Java since then, most of what was true then is still true in 2013.)

This module makes several references to my website, which is located at http://www.dickbaldwin.com/toc.htm .

Purpose of this module

This module explains anonymous classes from a practical viewpoint, including a comparison between anonymous classes and local classes.

Viewing tip

I recommend that you open another copy of this module in a separate browser window and use the following links to easily find and view the images and the listings while you are reading about them.

Images

Listings

Preview

What can you include in a class definition ?

There are several different kinds of items that can be included in a class definition. As you learned in the earlier modules in this series, the list includes:

  • Static variables
  • Instance variables
  • Static methods
  • Instance methods
  • Constructors
  • Static initializer blocks
  • Instance initializers

Can also contain other class definitions

As you also learned in previous modules, a class definition can also contain the following kinds of inner classes:

  • Member classes
  • Local classes
  • Anonymous classes
  • Nested top-level classes and interfaces

The previous two modules explained member classes and local classes. This module will explain anonymous classes.

What is an anonymous class ?

I'm going to begin my discussion with a quotation from one of my favorite authors, David Flanagan, author of Java in a Nutshell .

"An anonymous class is essentially a local class without a name."

If you have read the previous module, you should know quite a lot about local classes at this point in time. Continuing with Flanagan's words,

"Instead of defining a local class and then instantiating it, you can often use an anonymous class to combine these two steps... an anonymous class is defined by a Java expression , not a Java statement . This means that an anonymous class definition can be included within a larger Java expression..."

As you will see from the sample program in this module, anonymous class definitions are often included as arguments to method calls.

As is the case for an object of a member class or a local class (discussed in previous modules), an object of an anonymous class must be internally linked to an object of the enclosing class.

Thus, an anonymous class is truly an inner class, because an object of the anonymous class cannot exist in the absence of an object of the enclosing class.

What about an anonymous interface ?

Interfaces defined within classes are implicitly static. This means that they are always top-level. There is no such thing as a member interface, a local interface, or an anonymous interface.

Why use anonymous classes ?

As with local classes, objects instantiated from anonymous classes share many of the characteristics of objects instantiated from member classes. However, in some cases, an anonymous class can be defined closer to its point of use than would be possible with a member class or a local class. Once you become accustomed to the somewhat cryptic syntax used with anonymous classes, this can often lead to improved code readability.

Probably the most important benefit of anonymous classes has to do with accessing the members of enclosing classes. Just like with member classes and local classes, methods of an anonymous class have direct access to all the members of the enclosing classes, including private members. Thus the use of anonymous classes can often eliminate the requirement to connect objects together via constructor parameters.

In addition, although not demonstrated in this module, as with local classes, objects of anonymous classes have access to final local variables that are declared within the scope of the anonymous class.

Can be particularly useful when ...

An anonymous class can be particularly useful in those cases where

  • There is no reason for an object of the anonymous class to exist in the absence of an object of the enclosing class.
  • There is no reason for an object of the anonymous class to exist outside a method of the enclosing class.
  • Methods of the object of the anonymous class need access to members of the object of the enclosing class.
  • Methods of the object of the anonymous class need access to final local variables and method parameters belonging to the method in which the anonymous class is defined.
  • Only one instance of the anonymous class is needed.
  • There is no need for the class to have a name that is accessible elsewhere in the program.

Anonymous classes versus local classes

Once again, according to David Flanagan,

"...an anonymous class behaves just like a local class, and is distinguished from a local class merely in the syntax used to define and instantiate it."

Unlike a local class, however, an anonymous class cannot define a constructor. However, an anonymous class can define an instance initializer, which can provide some of the benefits of a constructor.

(I discussed instance initializers in detail in an earlier tutorial titled The Essence of OOP using Java, Instance Initializers . As you may recall, a primary shortcoming of an instance initializer as compared to a constructor is that an instance initializer cannot accept incoming parameters.)

Restrictions on the use of anonymous classes

Because an anonymous class has no name, and the definition and instantiation of the class appear in a single expression, only one instance of each anonymous class can be created. If you need more than one instance of the class, you should probably use a local class, a member class, or a top-level class instead.

As mentioned above, it is not possible to define constructors for anonymous classes. If you need to use a constructor when you instantiate the class, you should probably use a local class, a member class, or a top-level class instead.

As with member classes and local classes, anonymous classes cannot contain static members.

As with local variables and local classes, anonymous classes cannot be declared public , protected , private , or static . In fact, no modifiers can be specified in the definition of an anonymous class.

Smoke and mirrors

As I told you in my earlier modules on local classes, the methods in an anonymous class don't really have access to local variables and method parameters. Rather, when an object of the anonymous class is instantiated, copies of the final local variables and method parameters referred to by the object's methods are stored as instance variables in the object. The methods in the object of the anonymous class really access those hidden instance variables.

Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.

There are some additional activities involving smoke and mirrors taking place behind the scenes when you define and instantiate an anonymous class. Generally speaking, this involves the automatic generation of code to cause things to behave as they do. The good news is that you don't have to write that extra code, and you don't have to maintain it. The extra code is written for you, and if you modify your class structure, the extra code is automatically modified accordingly.

You can read about the code that is automatically generated in my earlier modules on local classes and member classes.

Syntax for anonymous classes

Before getting into actual code in the sample program, I want to explain the syntax used to define and instantiate an anonymous class.

The definition and instantiation of an anonymous class uses one or the other of the two expressions shown in Image 1 .

Usually, this expression is included inside a larger overall expression, such as an argument to a method call.

What does the first expression mean?

Here is how I usually explain this syntax to my students. The first expression in Image 1 starts out fairly normal, but becomes cryptic very quickly.

This expression instantiates a new object from an unnamed and previously undefined class. That class automatically extends the class named className , and cannot explicitly implement any interfaces.

The body of the new class is given by classBody .

The result of executing this expression is that:

  • a new class that extends className is defined,
  • a new object of the new class is instantiated, and
  • the expression is replaced by a reference to the new object.

Example usage

If this expression appears as the right operand of an assignment operator, the new object's reference is saved in the left operand of the assignment operator.

If the expression appears as an argument in a method call, the new object's reference is passed to the method.

If the expression appears in some other form of larger overall expression, the new object's reference is handed over to the surrounding expression to be used appropriately.

What about instantiating an interface?

The second expression in Image 1 starts out very weird. To my knowledge, there is no other situation in Java where you apply the new operator to the name of an interface.

From the beginning, you have been told (or should have been told) that you cannot instantiate an object of an interface. (An interface is implicitly abstract and it doesn't have a constructor, not even a default constructor.)

However, you can instantiate an object of a class that implements none, one, or more interfaces.

The correct interpretation of the second expression in Image 1 is as follows. This expression instantiates a new object from an unnamed and previously undefined class. That class automatically implements the interface named interfaceName , and it automatically extends the class named Object .

The class can explicitly implement one, and only one interface, and cannot extend any class other than Object .

Once again, the body of the new class is given by classBody .

As in the case of the first expression in Image 1 , the result of executing this second expression is that

  • a new class that implements interfaceName is defined,
  • a new object of the new class is instantiated, and
  • the expression is replaced by a reference to the new object.

That reference is handed over to the surrounding expression to be used appropriately.

What about constructor parameters?

As mentioned earlier in this module, since the new class doesn't have a name, it isn't possible to define a constructor for the new class.

According to Flanagan (with regard to the first expression in Image 1 ) ,

"Any arguments you specify between the parentheses following the superclass name in an anonymous class definition are implicitly passed to the superclass constructor."

Thus, it is possible to define an anonymous class that extends a class whose constructor requires parameters, and to pass those parameters to the superclass constructor when the anonymous class is instantiated.

The parentheses following interfaceName in the second expression in Image 1 must always be empty. In this case, the superclass is always Object , which never expects constructor parameters.

Discussion and sample code

The paragraphs that follow will explain a program named InnerClasses08 . This program is designed specifically to illustrate anonymous classes, and to compare anonymous classes with local classes.

I will discuss the program in fragments. A complete listing of the program is provided in Listing 10 .

When the program is executed, it produces the GUI shown in Image 2 . I will refer back to this image during the discussion of the program.

Class file names

This program consists of a total of six classes:

  • Two top-level classes
    • InnerClasses08.class
    • GUI.class
  • One local class
    • GUI$1$BaldButton.class
  • Three anonymous classes
    • GUI$1.class
    • GUI$2.class
    • GUI$3.class

When compiled, the program produces the class files shown in Image 3 .

(As you can see, the anonymous classes are not truly anonymous, since the files that represent them must have names. Generally, however, the establishment of the individual names is beyond the control of the programmer, and the names are not known to the program in a way that makes it possible to refer to them by name.)

Program structure and behavior

This program is designed to illustrate the use of local classes and anonymous classes in a very practical way. It illustrates one implementation of a local class and three different implementations of anonymous classes. The program compares the local class with an anonymous class designed to accomplish the same purpose. The program also illustrates the use of instance initializers as an alternative to constructors.

A local class

The program defines and uses a local class to instantiate an object to handle mouse clicked events on a button with low-level event handling. This class uses a constructor to enable mouse events on a new extended Button class. It also uses a constructor to display the name of the class file.

Three anonymous classes

An anonymous class to compare with the local class

The program also defines and uses an anonymous class to instantiate an object to handle mouse clicked events on a button with low-level event handling.

This class uses an instance initializer to enable mouse events on a new extended Button class. It also uses an instance initializer to display the name of the class file.

This class and the local class described above provide a direct comparison between the use of local classes and anonymous classes to serve the same purpose.

An anonymous class that implements an interface

The program illustrates the use of an anonymous class that implements the MouseListener interface, to instantiate an object to handle mouse clicked events using the source-listener event model (sometimes referred to as the delegation event model or the JavaBeans event model). The anonymous class uses an instance initializer to display the name of the class file.

An anonymous class that extends an existing class

The program illustrates the use of an anonymous class that extends the WindowAdapter class, to instantiate an object to handle window events fired by the close button in the upper-right corner of the Frame object shown in Image 2 . This class also uses the source-listener event model, and uses an instance initializer to display the name of the class file.

The screen output

The program produces the screen output shown in Image 4 when

  • The program is started
  • Each button shown in Image 2 is clicked once in succession, going from left to right
  • The close button in the upper-right corner of the Frame object in Image 2 is clicked

When the close button is clicked, the program produces the last line of text in Image 4 and terminates. I will identify the code that produces each line of output text in the discussion of the program that follows.

The controlling class

The controlling class for the program is shown in Listing 1 .

As you can see, the controlling class is very simple, with the main method instantiating an object of the GUI class. This results in the GUI that is pictured in Image 2 .

Local and anonymous classes inside GUI constructor

The local class and the three anonymous classes are defined inside the constructor for the GUI class.

(Recall that local classes and anonymous classes are defined inside code blocks, which often place them inside methods and constructors, but you can also place them inside static initializer blocks and instance initializers.)

The first four lines of the output text in Image 4 are produced by constructors and instance initializers in the local and anonymous classes. Therefore, those four lines of text are produced when the new object of the GUI class is instantiated.

The GUI class

As is often the case, the GUI class used to create the visual GUI shown in Image 2 consists solely of a constructor. Basically, this constructor

  • places three buttons in the frame and
  • registers event handlers on the buttons and on the frame.

Once the GUI object is constructed and appears on the screen, all further activity in the program occurs under control of the event handlers associated with the buttons and the frame.

(You can learn more about event handling here .)

The GUI constructor

The GUI class, and the constructor for that class begin in Listing 2 .

As you can see, the GUI class extends Frame , so that an object of the class is a frame.

The constructor code shown in Listing 2 simply sets values for the layout, size, and title properties of the frame.

The BaldButton class

The definition of the BaldButton class begins in Listing 3 . This is a local class that extends Button .

Extending the Button class makes it possible to override the processMouseEvent method in order to handle mouse events that are fired by the button.

This is a form of low-level event handling that will be contrasted with source-listener event handling later in the program.

Listing 3 shows the constructor for the BaldButton class.

Enable mouse events

The most important code in the constructor is the statement that enables mouse events on the button.

If you are unfamiliar with the enableEvents method, you should look it up in the Sun documentation. Briefly, this method must be called on the button to cause the overridden processMouseEvent method to be called later when the button fires a mouse event.

The remaining constructor code

The remaining code in the constructor

  • Sets the text value on the face of the button
  • Gets and displays the name of the class file that represents this local class

The screen output

Construction of the button by the code in Listing 3 causes the text shown in Image 5 to appear on the screen. This is how I was able to identify the name of the class file that represents the local class in my earlier discussion of class file names.

We will see later that this button will be added as the leftmost button in the GUI shown in Image 2 .

The processMouseEvent method

Continuing with the constructor for the BaldButton class, Listing 4 shows the overridden processMouseEvent method for an object of the BaldButton class.

This method is called each time an object instantiated from this class fires a mouse event. That is why I refer to the method as an event handler for the button.

Different kinds of mouse events A button can fire a variety of different kinds or subcategories of mouse events :

  • MOUSE_CLICKED
  • MOUSE_DRAGGED
  • MOUSE_ENTERED
  • MOUSE_EXITED
  • MOUSE_MOVED
  • MOUSE_PRESSED
  • MOUSE_RELEASED

In this case, I elected to ignore all but MOUSE_CLICKED . This subcategory of mouse event occurs when a mouse button is pressed and then released.

The code in the event handler of Listing 4 first confirms that the event was of the MOUSE_CLICKED variety. If so, it displays a message that matches the fifth line of text in the output shown in Image 4 .

Call processMouseEvent on the superclass

Without getting into the details of why this is required, I'm simply going to tell you that when you use this low-level event model to handle events, your overridden processMouseEvent method must call the same method in the superclass, passing the incoming parameter of type MouseEvent as a parameter to the superclass version of the method.

Add a button to the frame

The last statement in Listing 4 instantiates a new BaldButton object, setting the text on the face of the button to A , and adds that new object to the frame.

Because the layout property of the frame has been set to FlowLayout , and because this is the first component added to the frame, this button appears as the leftmost button in the GUI shown in Image 2 .

Could instantiate multiple buttons of this type

Although I instantiated the button object as an anonymous object in this case, that wasn't necessary. Using this local class, I could instantiate more than one object of this type, saving the object's references in reference variables of the appropriate type. Later we will see that this is not possible for anonymous classes.

It is interesting to note, however, that with this event handling model, if I were to instantiate multiple buttons of this type, the same processMouseEvent method would be called no matter which of the buttons fired a mouse event. If I wanted different behavior as a result of the different buttons firing mouse events, I would have to write code inside the processMouseEvent method to deal with that issue.

The source-listener event model that I will illustrate later doesn't suffer from that restriction.

An anonymous inner class for low-level event handling

Listing 5 shows the beginning of an anonymous class to perform low-level event handling similar to that shown in Listing 4 .

This code defines an anonymous inner class that implicitly extends Button and has mouse events enabled. I provided this class primarily for comparison with the local class named BaldButton . This class is an anonymous alternative to the local BaldButton class.

An argument to the add method

Note that the definition of this anonymous class appears as an argument to the add method for the frame. Thus, the anonymous object instantiated from the anonymous class is added as the second (middle) button in Image 2 .

Extends the Button class

Note also that this form of anonymous class implicitly extends the Button class. Once again, this makes it possible to override the processMouseEvent method belonging to the Button class.

An instance initializer

As I mentioned earlier in this module, it is not possible to define a constructor for an anonymous class. However, it is possible to define an instance initializer.

(In Listing 5 , the instance initializer consists of two statements enclosed by matching curly brackets.)

This class defines an instance initializer that

  • Enables mouse events on an anonymous object instantiated from the anonymous class.
  • Gets and displays the name of the class file that represents the anonymous class.

The screen output

Therefore, the instantiation of this anonymous object causes the text shown in Image 6 to appear on the screen. About all you can tell by looking at this class name is that it is the name of a file that represents an anonymous class.

Overridden processMouseEvent method

The remaining code in the anonymous class definition is shown in Listing 6 . The code in Listing 6 consists of

  • an overridden processMouseEvent method, plus
  • the curly brackets, parentheses, and semicolon necessary to complete the expression and the statement.

Same code as before

The code in this overridden processMouseEvent method is essentially the same as that shown for the local class in Listing 4 , except that it produces a different message on the screen when the user clicks the button.

Clicking the middle button in Image 2 produces the screen output shown by the sixth line in Image 4 .

Instantiating and registering a MouseListener object

Implementing a listener interface

Now I'm going to switch from low-level event handling to source-listener event handling. The code to accomplish this begins in Listing 7 .

With this event handling model:

  • A listener object is instantiated from a class that implements a specific listener interface. In this case, that interface will be the MouseListener interface.
  • The listener object is registered on an object that knows how to fire events of a type that is associated with the listener interface. In this case, that will be events of type MouseEvent .
  • When the source object fires an event of the specified type, one of the methods belonging to the registered listener object will be called to handle the event. The different methods belonging to the listener object are declared in the implemented listener interface.

Listing 7 begins by instantiating a new Button object.

(Note that with this event model, it is not necessary to extend the Button class, because it is not necessary to override methods belonging to the Button object.)

Register a MouseListener object

After instantiating the Button object, the code in Listing 7 calls the addMouseListener method to register a MouseListener object on that button. The argument to the addMouseListener method must be a reference to an object instantiated from a class that implements the MouseListener interface.

Instantiate the listener object

In this case, that listener object is created by

  • writing an expression to instantiate an anonymous object from an anonymous class and
  • placing that expression as an argument to the addMouseListener method.

Implement the MouseListener interface

The definition of the anonymous class in this example uses the syntax that implements an interface.

An instance initializer

As before, an instance initializer is used to get and display the name of the class file that represents the anonymous class. Thus, when the new anonymous object of the anonymous class is instantiated, the text shown in Image 7 appears on the screen.

Note the similarity of this class file name to that shown earlier in Image 6 . (You can also compare them in Image 4 .) The names of the two class files differ only with respect to a number that is provided by the compiler to guarantee that each class file name is unique.

Implementing the interface

Whenever a class implements an interface, it must provide a concrete definition for each of the methods declared in the interface, even if some of those methods are empty.

Continuing with the definition of the anonymous class, Listing 8 provides definitions for all five of the methods declared in the MouseListener interface. Four of those methods are defined as empty methods.

Separation of event subcategories

One of the major differences between the low-level event model discussed earlier and the source-listener model being discussed here has to do with where the separation between the different subcategories (mouseClicked, mousePressed, mouseReleased, etc.) of a given event type is accomplished.

In the low-level model, the separation must be accomplished by code in the overridden event handler method, such as with the if statement in the processMouseEvent method defined in Listing 6 .

In the source-listener model, the separation is accomplished before the event handler method is called, and a specific event handler method, such as the mouseClicked method is called on the listener object.

When the button fires a mouse event ...

In this case, whenever the button fires a MouseEvent of the MOUSE_CLICKED subcategory , the mouseClicked method defined in Listing 8 will be called automatically, causing the seventh line of text in Image 4 to appear on the screen.

Whenever the button fires a MouseEvent of one of the other subcategories , one of the empty methods defined in Listing 8 will be called. This method will return immediately, doing nothing but wasting a little computer time.

(In case you are wondering what happened to the mouseMoved and mouseDragged methods, they are defined in the MouseMotionListener interface instead of the MouseListener interface.)

Add the button to the frame

Finally, the last statement in Listing 8 adds the new button to the Frame as the rightmost button in Image 2 .

A disclaimer

I wrote this code the way that I did in Listing 8 to illustrate an anonymous class that implements an interface. In real life, I would probably cause the anonymous class to extend the MouseAdapter class and override the mouseClicked method instead of implementing the MouseListener interface. That would eliminate the requirement for me to define the four empty methods in Listing 8 .

Extending the WindowAdapter class

The above disclaimer provides a perfect lead-in to the definition of the anonymous class shown in Listing 9 .

Registering a WindowListener on the Frame

The code in Listing 9 instantiates an anonymous object of an anonymous class that extends the WindowAdapter class.

That anonymous object is registered as a WindowListener on the Frame by passing the object's reference to the addWindowListener method belonging to the Frame .

(The addWindowListener method requires an incoming parameter of type WindowListener . This is satisfied by the fact that the WindowAdapter class implements the WindowListener interface. Thus, an object instantiated from a class that extends WindowAdapter can also be treated as type WindowListener .)

The screen output

This anonymous class definition uses an instance initializer to get and display the name of the class that represents the anonymous class. Thus, when the anonymous object of the anonymous class is instantiated, the text shown in Image 8 appears on the screen.

(In an earlier module explaining member classes, I told you that it is possible to examine the names of the class files that represent the member classes and to determine quite a lot about the structure of the program in terms of which classes are members of which other classes. However, in the case of local classes and anonymous classes, about all that you can determine from the name of the class file is that the file either represents a local class or represents an anonymous class (see the summary of class names in Image 3 ).)

The windowClosing method

The code in Listing 9 overrides the windowClosing method inherited from the WindowAdapter class.

Clicking the close button with the X in the upper right hand corner of Image 2 causes the windowClosing method to be called on any WindowListener objects that have been registered on the frame.

In this case, the overridden windowClosing method in Listing 9 causes the last line of text in Image 4 to be displayed on the screen.

Following that, the overridden windowClosing method calls the System.exit method to terminate the program.

The remaining code

The remaining code in Listing 9

  • Causes the frame to become visible
  • Signals the end of the constructor
  • Signals the end of the GUI class

The GUI remains on the screen until terminated

Once the constructor is executed, the GUI simply remains on the screen waiting for someone to click one of the buttons or to click the close button in the upper right corner of the frame. When these buttons are clicked, the event handlers are called, causing text such as that shown in Image 9 to appear on the screen.

Simple event handlers

In this demo program, the event handlers simply display messages on the screen, and in the case of the close button, terminate the program. In a real world program, the behavior of the event handlers would likely be much more substantive, but the overall skeleton of the program need not be any different from that illustrated here.

Run the program

I encourage you to copy the code from Listing 10 . Compile the code and execute it. Experiment with the code, making changes, and observing the results of your changes. Make certain that you can explain why your changes behave as they do.

Summary

In addition to a number of other items, a class definition can contain:

  • Member classes
  • Local classes
  • Anonymous classes
  • Nested top-level classes and interfaces

Member classes and local classes were explained in previous modules. This module explains anonymous classes.

Although there are some differences, an anonymous class is very similar to a local class without a name. Instead of defining a local class and then instantiating it, you can often use an anonymous class to combine these two steps.

An anonymous class is defined by a Java expression, not a statement. Therefore, an anonymous class definition can be included within a larger overall Java expression.

Anonymous class definitions are often included as arguments to method calls, or as the right operand of assignment operators.

An object of an anonymous class must be internally linked to an object of the enclosing class.

There is no such thing as an anonymous interface, a local interface, or a member interface.

An anonymous class can often be defined very close to its point of use. Once you become accustomed to the somewhat cryptic syntax used with anonymous classes, this can lead to improved code readability.

Probably the most important benefit of anonymous classes has to do with accessing the members of enclosing classes. As with member classes and local classes, methods of an anonymous class have direct access to all the members of the enclosing classes, including private members. Thus the use of anonymous classes can sometimes eliminate the requirement to connect objects together via constructor parameters. In addition, objects of anonymous classes have access to final local variables that are declared within the scope of the anonymous class.

An anonymous class can be particularly useful in those cases where

  • There is no reason for an object of the anonymous class to exist in the absence of an object of the enclosing class.
  • There is no reason for an object of the anonymous class to exist outside a method of the enclosing class.
  • Methods of the object of the anonymous class need access to members of the object of the enclosing class.
  • Methods of the object of the anonymous class need access to final local variables and method parameters belonging to the method in which the anonymous class is defined.
  • Only one instance of the anonymous class is needed.
  • There is no need for the class to have a name that is accessible elsewhere in the program.

An anonymous class cannot define a constructor. However, it can define an instance initializer.

Any arguments that you specify between the parentheses following the superclass name in an anonymous class definition are implicitly passed to the superclass constructor.

Only one instance of an anonymous class can be created.

As with member classes and local classes, anonymous classes cannot contain static members.

As with local variables and local classes, anonymous classes cannot be declared public , protected , private , or static .

Miscellaneous

This section contains a variety of miscellaneous information.

Note:

Housekeeping material
  • Module name: Java OOP: Anonymous Classes
  • File: Java1640.htm
  • Published: 11/20/13

Note:

Disclaimers:

Financial : Although the Connexions site makes it possible for you to download a PDF file for this module at no charge, and also makes it possible for you to purchase a pre-printed version of the PDF file, you should be aware that some of the HTML elements in this module may not translate well into PDF.

I also want you to know that, I receive no financial compensation from the Connexions website even if you purchase the PDF version of the module.

In the past, unknown individuals have copied my modules from cnx.org, converted them to Kindle books, and placed them for sale on Amazon.com showing me as the author. I neither receive compensation for those sales nor do I know who does receive compensation. If you purchase such a book, please be aware that it is a copy of a module that is freely available on cnx.org and that it was made and published without my prior knowledge.

Affiliation : I am a professor of Computer Information Technology at Austin Community College in Austin, TX.

Complete program listing

A complete listing of the program discussed in this module is show in Listing 10 .

Images

Figure 1: Image 1: Syntax for anonymous classes.
Image 1: Syntax for anonymous classes.

new className(optional argument list){classBody}

new interfaceName(){classBody}
Figure 2: Image 2: Program GUI.
Image 2: Program GUI.
Missing image
Figure 3: Image 3: Class file names.
Image 3: Class file names.
GUI$1$BaldButton.class
GUI$1.class
GUI$2.class
GUI$3.class
GUI.class
InnerClasses08.class
Figure 4: Image 4: Screen output.
Image 4: Screen output.
Local class name: GUI$1$BaldButton
Anonymous class B name: GUI$1
Anonymous class C name: GUI$2
Anonymous window listener class name: GUI$3
buttonA clicked
buttonB clicked
buttonC clicked
Close button clicked
Figure 5: Image 5: Screen output.
Image 5: Screen output.
Local class name: GUI$1$BaldButton
Figure 6: Image 6: Screen output.
Image 6: Screen output.
Anonymous class B name: GUI$1
Figure 7: Image 7: Screen output.
Image 7: Screen output.
Anonymous class C name: GUI$2
Figure 8: Image 8: Screen output.
Image 8: Screen output.
Anonymous window listener class name: GUI$3
Figure 9: Image 9: Screen output.
Image 9: Screen output.
buttonA clicked
buttonB clicked
buttonC clicked
Close button clicked

Listings

Listing 1: The controlling class.

public class InnerClasses08 {
  public static void main(String[] args){
    new GUI();
  }//end main
}//end class InnerClasses08

Listing 2: Beginning of the GUI class.

class GUI extends Frame{
  public GUI(){//constructor
    setLayout(new FlowLayout());
    setSize(250,75);
    setTitle("Copyright 2003 R.G.Baldwin");

Listing 3: Beginning of the BaldButton class.

    class BaldButton extends Button{
      BaldButton(String text){//constructor
        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
        setLabel(text);
        System.out.println("Local class name: " +
                           getClass().getName());
      }//end constructor

Listing 4: The processMouseEvent method.


      public void processMouseEvent(MouseEvent e){
        if (e.getID() == MouseEvent.MOUSE_CLICKED){
          System.out.println("buttonA clicked");
        }//end if

        //The following is required of overridden
        // processMouseEvent method.
        super.processMouseEvent(e);
      }//end processMouseEvent
    }//end class BaldButton

    //Add button to Frame
    add(new BaldButton("A"));

Listing 5: Beginning of anonymous inner class.

    add(new Button("B")
      {//Begin class definition
        {//Instance initializer
          enableEvents(
                      AWTEvent.MOUSE_EVENT_MASK);
          System.out.println(
                     "Anonymous class B name: " +
                           getClass().getName());
        }//end instance initializer

Listing 6: Overridden processMouseEvent method.

        public void processMouseEvent(
                                    MouseEvent e){
          if (e.getID() ==
                        MouseEvent.MOUSE_CLICKED){
            System.out.println("buttonB clicked");
          }//end if

          //Required of overridden
          // processMouseEvent method.
          super.processMouseEvent(e);
        }//end processMouseEvent
      }//end class definition
    );//end add method call

Listing 7: Register a MouseListener object.

    Button buttonC = new Button("C");

    buttonC.addMouseListener(new MouseListener()
      {//begin class definition
        //Instance initializer
        {System.out.println(
                     "Anonymous class C name: " +
                          getClass().getName());}

Listing 8: Implementing the interface.

        public void mouseClicked(MouseEvent e){
          System.out.println("buttonC clicked");
        }//end mouseClicked

        //All interface methods must be defined
        public void mousePressed(MouseEvent e){}
        public void mouseReleased(MouseEvent e){}
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}

      }//end class definition
    );//end addMouseListener call

    add(buttonC);//add button to frame

Listing 9: Registering a WindowListener on the Frame .

    addWindowListener(new WindowAdapter()
      {//begin class definition
        //Instance initializer
        {System.out.println(
             "Anonymous window listener class " +
               "name: " + getClass().getName());}

        public void windowClosing(WindowEvent e){
          System.out.println(
                         "Close button clicked");
          System.exit(0);
        }//end windowClosing
      }//end class definition
    );//end addWindowListener

    setVisible(true);

  }//end constructor
}//end GUI class

Listing 10: Complete program listing.

/*File InnerClasses08.java
Copyright 2003 R.G.Baldwin

This program is designed to illustrate the use
of local classes, and anonymous classes.  It
illustrates three different implementations of
anonymous classes.  It also illustrates the use
of instance initializers as an alternative to
constructors.

Illustrates use of local class to instantiate
object to handle mouse clicked event with
low-level event handling.  This class uses
constructor to enable mouse events on a new
extended Button class.  Also uses constructor
to display the class file name.

Illustrates use of anonymous class to instantiate
object to handle mouse clicked event with
low-level event handling.  This class uses an
instance initializer to enable mouse events on a
new extended Button class.  Also uses instance
initializer to display name of class file.

Illustrates use of anonymous class, which
implements MouseListener interface, to
instantiate object to handle mouse clicked event
using source-listener event model.  Uses instance
initializer to display name of class file.

Illustrates use of anonymous class, which extends
WindowAdapter class, to instantiate object to
handle window events fired by the close button in
the upper-right corner of a Frame object, using
source-listener event model.  Uses instance
initializer to display name of class file.

This program produces the following class files
when compiled:

GUI$1$BaldButton.class
GUI$1.class
GUI$2.class
GUI$3.class
GUI.class
InnerClasses08.class

The program produces the following output when
the program is started, each button is clicked
once in succession, and then the close button
in the upper-right corner of the Frame is
clicked:

Local class name: GUI$1$BaldButton
Anonymous class B name: GUI$1
Anonymous class C name: GUI$2
Anonymous window listener class name: GUI$3
buttonA clicked
buttonB clicked
buttonC clicked
Close button clicked

Tested using JDK 1.4.1 under Win
************************************************/

import java.awt.*;
import java.awt.event.*;

public class InnerClasses08 {
  public static void main(String[] args){
    new GUI();
  }//end main
}//end class InnerClasses08
//=============================================//

class GUI extends Frame{

  public GUI(){//constructor
    setLayout(new FlowLayout());
    setSize(250,75);
    setTitle("Copyright 2003 R.G.Baldwin");

    //Local class w/mouse events enabled. The new
    // class extends Button, and uses low-level
    // event handling to handle mouse clicked
    // events on the button.
    class BaldButton extends Button{
      BaldButton(String text){//constructor
        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
        setLabel(text);
        //Display the name of the class file
        System.out.println("Local class name: " +
                           getClass().getName());
      }//end constructor

      //This is the event handling method.
      public void processMouseEvent(
                                   MouseEvent e){
        if (e.getID() ==
                       MouseEvent.MOUSE_CLICKED){
          System.out.println("buttonA clicked");
        }//end if
        //The following is required of overridden
        // processMouseEvent method.
        super.processMouseEvent(e);
      }//end processMouseEvent
    }//end class BaldButton

    //Add button to Frame
    add(new BaldButton("A"));


    //This code defines an anonymous Inner Class
    // w/mouse events enabled.  The new class
    // extends Button.  This class uses low-level
    // event handling to handle mouse clicked
    // events on the button.  This is an
    // anonymous alternative to the local class
    // defined above.
    add(new Button("B")
      {//Begin class definition
        {//Instance initializer
          enableEvents(
                      AWTEvent.MOUSE_EVENT_MASK);
          System.out.println(
                     "Anonymous class B name: " +
                           getClass().getName());
        }//end instance initializer

        //Override the inherited
        // processMouseEvent method.
        public void processMouseEvent(
                                   MouseEvent e){
          if (e.getID() ==
                       MouseEvent.MOUSE_CLICKED){
            System.out.println(
                              "buttonB clicked");
          }//end if
          //Required of overridden
          // processMouseEvent method.
          super.processMouseEvent(e);
        }//end processMouseEvent
      }//end class definition
    );//end add method call


    Button buttonC = new Button("C");
    //Anonymous inner class that implements
    // MouseListener interface
    buttonC.addMouseListener(new MouseListener()
      {//begin class definition
        //Instance initializer
        {System.out.println(
                     "Anonymous class C name: " +
                          getClass().getName());}

        public void mouseClicked(MouseEvent e){
          System.out.println("buttonC clicked");
        }//end mouseClicked

        //All interface methods must be defined
        public void mousePressed(MouseEvent e){}
        public void mouseReleased(MouseEvent e){}
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}

      }//end class definition
    );//end addMouseListener call

    add(buttonC);//add button to frame


    //Use an anonymous class to register a window
    // listener on the Frame.  This class extends
    // WindowAdapter
    addWindowListener(new WindowAdapter()
      {//begin class definition
        //Instance initializer
        {System.out.println(
             "Anonymous window listener class " +
               "name: " + getClass().getName());}

        public void windowClosing(WindowEvent e){
          System.out.println(
                         "Close button clicked");
          System.exit(0);
        }//end windowClosing
      }//end class definition
    );//end addWindowListener

    setVisible(true);

  }//end constructor

}//end GUI class
//=============================================//

-end-

Collection Navigation

Content actions

Download:

Collection as:

EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Module as:

PDF | EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Add:

Collection to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks

Module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks