Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login




Remember Me
Forgot Password?
Join Us!

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Jobs from Indeed

Link To This Forum!

Partner Button
Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Starting out with Java

Anonymous Inner Classes
Posted: 30 Apr 02 (Edited 2 May 02)

An inner class is where you define one class within another. You might do this where one class is tightly coupled to another class and there is no point in defining a new class.

// Outer.java
public class Outer {
    Outer() {
        Inner i = new Inner();
        i.innerMethod();
    }

    // Inner class
    private class Inner {
        Inner() {}

        public void innerMethod() {
            // Do something.
        }
    }
}

Anonymous inner classes are classes that are created in situ within a method and can only be used once, where they are defined.

One classic use for an anonymous inner class is to implement the WindowListener interface in a Window. This lets a Window react to a number of standard window events, including reacting to the close button. The Window Listener interface dictates that an implementing class must define a number of methods. The Window class has a method addWindowListener(WindowListener) that allows the Window to receive window events.

So, you have a class that extends Frame (which is a subclass of Window):

// MyFrame.java
import java.awt.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
    }
}

If you want to now add a WindowListener to the above, you have to first define a class that implements WindowListener, instantiate it and add it:

// MyWindowListener.java
import java.awt.event.*;
public class MyWindowListener implements WindowListener {
    public void windowOpened(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {System.exit(0);}
    public void windowClosed(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowActivated(WindowEvent e) {}
    public void windowDeactivated(WindowEvent e) {}
}

// MyFrame.java
import java.awt.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
        MyWindowListener myWindowListener = new MyWindowListener();
        addWindowListener(myWindowListener);
    }
}

Okay, the above will work but MyWindowListener is a bit trivial. It would be nice if it were associated with MyFrame. And it can be, as an inner class:

// MyFrame.java
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
        addWindowListener(new MyWindowListener());
    }

    private class MyWindowListener implements WindowListener {
        public void windowOpened(WindowEvent e) {}
        public void windowClosing(WindowEvent e) {System.exit(0);}
        public void windowClosed(WindowEvent e) {}
        public void windowIconified(WindowEvent e) {}
        public void windowDeiconified(WindowEvent e) {}
        public void windowActivated(WindowEvent e) {}
        public void windowDeactivated(WindowEvent e) {}
    }
}

Much better. Now the WindowListener is not out on its own but inside the only class that is likely to use it.

But we can go one further with an anonymous inner class. Instead of going to the bother of creating MyWindowListener, we can define and add the WindowListener in one go:

// MyFrame.java
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
        WindowListener w = new WindowListener() {
            public void windowOpened(WindowEvent e) {}
            public void windowClosing(WindowEvent e) {System.exit(0);}
            public void windowClosed(WindowEvent e) {}
            public void windowIconified(WindowEvent e) {}
            public void windowDeiconified(WindowEvent e) {}
            public void windowActivated(WindowEvent e) {}
            public void windowDeactivated(WindowEvent e) {}
        };
        addWindowListener(w);
    }
}

Here, WindowListener w is created with the default constructor WindowListener(). Usually this would fail because WindowListener is an interface (not a class) and it does not support the required methods. But the interface methods are immediately implemented in a block within the braces following the constructor, so Java is happy. Usually you miss out the intermediate step of creating w and do this:

// MyFrame.java
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
        addWindowListener(new WindowListener() {
            public void windowOpened(WindowEvent e) {}
            public void windowClosing(WindowEvent e) {System.ext(0);}
            public void windowClosed(WindowEvent e) {}
            public void windowIconified(WindowEvent e) {}
            public void windowDeiconified(WindowEvent e) {}
            public void windowActivated(WindowEvent e) {}
            public void windowDeactivated(WindowEvent e) {}
        });
    }
}

Anonymous inner classes can appear a bit confusing to start with and are sometimes difficult to notice in other programmer’s code. The "});" is usually a telltale. They can cut down on trivial classes that you only need the once though, especially if you use an adapter class:

// MyFrame.java
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends Frame {
    MyFrame() {
        super("MyFrame");
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.ext(0);}
        });
    }
}

WindowAdapter implements all the methods required by the WindowListener interface. These methods do absolutely nothing, so you have to override the methods that you need, but you do not have to worry about the ones in which you are not interested.

When you compile a class with an anonymous inner class you get two compiled class files: in the above you get Frame.class and MyFrame$1.class.

If the class you are using as the base (e.g. WindowAdapter) has constructors that take arguments, there is nothing to stop you using these, but you cannot define new constructors for anonymous inner classes (because you do not get a chance to use them).

Usually the hardest bit about writing anonymous inner classes is getting the braces and parentheses and so forth to match up, so it is advisable to get things to compile at an early stage before tackling the method details. As a rule inner classes are small, convenience classes; if you find that you are having to write lots of detail in an inner class, it is probably time to separate it out into its own file.

-----------

P.S.   To make any of the above runnable, add a main method to MyFrame:

    public static void main(String[] args) {
        MyFrame mf = new MyFrame();
        mf.show();
    }


Back to Java FAQ Index
Back to Java Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close