3

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?

Chris Cashwell
  • 22,308
  • 13
  • 63
  • 94

7 Answers7

6

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.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • 1
    To be fair, OP went out of his way to turn 2 lines into 6 by using a switch statement instead of an if statement. – corsiKa Dec 12 '11 at 14:12
  • @glowcoder It is 6 lines to get at the point: when is it _appropriate_ to use anonymous inner classes. I could have just as well done the same thing in two lines, but wanted to see answers related to length of code (practical usage) as well as functional usage. – Chris Cashwell Dec 12 '11 at 14:21
  • I prefer to add methods to enums. In this case I'd define method `proceedBrowserEvent` and implement it for each member of enum. In this case the listener should really invoke one method, so it will be one line long. – AlexR Dec 12 '11 at 14:21
3

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)

MK.
  • 33,605
  • 18
  • 74
  • 111
  • Yeah, the fact that you need to manually capture them sucks, but it's just syntactic, not functional deficiency. – MK. Dec 12 '11 at 15:05
1

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.

solendil
  • 8,432
  • 4
  • 28
  • 29
1

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • What do you mean by `poor event handling`? – Peter Lawrey Dec 12 '11 at 14:33
  • In the OP, I mentioned that "Doodads have poor event handling." Let's say that it improperly handles clicks when it has been `disabled`. – Chris Cashwell Dec 12 '11 at 14:34
  • Whether the class is named or anonymous makes no difference to its behaviour (Other than the default `toString`) and if it has `poor event handling` it will still have this if it were named. – Peter Lawrey Dec 12 '11 at 14:37
0

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)

SJuan76
  • 24,532
  • 6
  • 47
  • 87
0

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()'

Andrew Fielden
  • 3,751
  • 3
  • 31
  • 47
0

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);.

Dunes
  • 37,291
  • 7
  • 81
  • 97