Chris Cashwell
Chris Cashwell

Reputation: 22859

Anonymous Inner Classes: When are they (in)appropriate?

Take the following example. There's an object I want to use, call it a Doodad. Doodad elements have poorly implemented handling of browser events. Typical instantiation of a Doodad would be Doodad someDoodad = new Doodad();. Obviously this isn't suiting my needs because of the poor event handling. Is it appropriate for me to override the onBrowserEvent() method, like so:

Doodad someDoodad = new Doodad() {
@Override
  public void onBrowserEvent(Event event) {
      switch (DOM.eventGetType(event)) {
          case Event.ONDBLCLICK:
          case Event.ONFOCUS:
          case Event.ONCLICK:
              if (!isEnabled()) {
                  return;
              }
              break;
      }
      super.onBrowserEvent(event);
  }
};

Obviously this is a simple example, but when might I not want to use an anonymous inner class? Is it ever explicitly disallowed or impossible?

I'm seeing lots of answers to the first question, but none of the answers so far answer the second: Is it ever explicitly disallowed or impossible to use an anonymous inner class?

Upvotes: 3

Views: 1194

Answers (7)

MK.
MK.

Reputation: 34537

Anonymous inner classes is Java's syntax for creating closures. Here's an approximate example:

interface Adder {
  int add(int arg);
}

...

Adder createAdder(int n) {
   final int nf = n;
   return new Adder() { 
       int add(int arg) { return arg + nf; } 
   }
}

Method createAdder creates what essentially is a function using a closure to capture the passed value n. Closures are important in functional programming which is trying to make it into mainstream. This is why everyone is screaming that we need "real" closures in Java (i.e. mostly better syntax than in my example).

(Of course I'm not answering the question asked; I think what I'm saying is that anonymous classes are good for what I described above. for almost everything else I would create a named inner class because if anything name is self-documenting and is in my opinion easier to read)

Upvotes: 3

Dunes
Dunes

Reputation: 40703

In your example you would want to create a separate class. This is because of the reason why you are overriding the method. That is, there is poor handling for browser events.

Specifically, you may want to create these improved Doodads in a couple of different places. And what happens if the event handling is updated and improved in the future? You'll want to remove all of these improved Doodads and use the proper implementation. Trying to find all your anonymous Doodads may be tiresome or tricky. Whereas if you have a separate named class then refactoring out this class will be easy.

In addition the reason for your improving the Doodad can be self documenting if you create a separate class for it. Whereas if you just have an anonymous class then you will have to write comments or leave future maintainers guessing why you've done what you've done.

eg.

public class ImprovedBrowserEventHandlingDoodad extends Doodad {
    ...
}

Anything that resembles a closure is normally a good candidate for using an anonymous class

eg.

new Thread(new Runnable() {
    @Override
    public void run() {
        doSomething();
    }
}).start();

You only want to do something in this one specific set of circumstances and there is no need to copy and paste the code somewhere else or to refactor it into a method.

Event handlers for GUIs are typical in using anonymous classes because their use is limited to the how the GUI is designed and there is no need to create a separate instance of the event handler outside the specific component that is using it. For instance, when you mouse over a scroll bar its appearance generally changes. Nothing else in the program will cause this change and typically the event handler will be a couple of lines telling the scrollbar to change its appearance eg. scrollbar.setMouseOverEffect(true);.

Upvotes: 0

Andrew Fielden
Andrew Fielden

Reputation: 3899

I only use an anonymous inner class when it contains a very small amount of code. Reason is IMO it clutters up the code and makes it less readable.

If there is more code required, I prefer to create a new class, extending the base class (in this case 'Doodad()'

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533492

I would suggest anonymous classes when it implements one method and/or is half a screen full.

If the anonymous has non trival piece of code its worth having a named class IMHO.

Upvotes: 1

solendil
solendil

Reputation: 8468

Often, an event listener is a piece of code that is not very generic, but is tied to a specific widget, a button, a text-field, whatever. In such a case, the code does not need to be properly exposed for the world to reuse it. It is easier to define it where it is used, in place, and that's what anonymous inner classes are for. They allow to quickly embed pieces of code inside another method, without having to worry about class names, packages, visibility, or re-usability.

Of course, what you can do with anonymous inner classes can always be done with proper stand-alone classes. But it makes more sense to do it this way when your event handling class is generic enough (can handle lots of events), is reusable, is stateful, or more generally when there is some benefit from extracting the event management code from the code that defines the event-generating element.

I'm not sure I understand specifically your question, I hope this piece of info will help you find your answer. Do not hesitate to ask further questions.

Upvotes: 1

SJuan76
SJuan76

Reputation: 24780

My take:

Anonymous inner classes: Callback from one function (so you don't write the code twice)

Named inner classes: Callbacks from several functions (or a class that you need only for the internal logic of the parent class)

Upvotes: 0

AlexR
AlexR

Reputation: 115328

Typically the best usage of anonymous inner classes is when you want to create only one instance of specific implementation of this class. And when the implementation is pretty simple. Ideally it should contain 1-2 lines of code.

In your case it is still OK although your method onBrowserEvent() is longer than 2 lines.

Upvotes: 6

Related Questions